When it comes to sending newsletters, 8 thousand recipients are not a high number, let alone a number that will consume all available memory.
What seems to be missing is an optimization of the objects in use so as not to fill the memory with the same information repeated 8 thousand times.
Possible optimization
function enviarNewsletterUsuarios() {
// recolher os destinatários
$usuarios = getUsuarios();
// se temos destinatários
if ($usuarios) {
/* Preparar o envio definindo os valores comuns
*/
$mail = new PHPMailer;
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'host'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'user'; // SMTP username
$mail->Password = 'pass'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted
$mail->From = 'teste';
$mail->FromName = 'teste';
$mail->WordWrap = 50; // Set word wrap to 50 characters
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Newsletter';
$mail->Body = utf8_decode('tesste');
/* Por cada destinatário enviar o email
*/
foreach ($usuarios as $usuario) {
$mail->addAddress($usuario->email); // Add a recipient
if ($mail->send()) {
// acção quando correu bem
} else {
// correu mal :(
}
/* Limpa a lista de destinatários para evitar que o email
* a enviar vá acumulando destinatários
*/
$mail->ClearAllRecipients();
}
return true;
}
}
In your code I noticed also that you have:
$objetivo = getObjetivo($usuario->guid);
$ideias = getIdeiaPorObjetivo($objetivo, $usuario->cidade);
In the case of something that is going to be "injected" into the body of the email or the subject of the email, I already recommend a queue sending in database because the job of sending the email is this even send the email. The information on it should be ready and ready to use or actually face high memory consumption issues.
Example of a table for queue of newsletters:
CREATE TABLE IF NOT EXISTS 'newsletter_queue' (
'id' int(13) NOT NULL AUTO_INCREMENT COMMENT 'Internal ID',
'newsletter_id' int(13) NOT NULL COMMENT 'ID from the table "newsletter"',
'entity_id' int(13) NOT NULL COMMENT 'ID from the table "entity".',
'entity_type' enum('entity','subscriber','admin user','unknown') NOT NULL DEFAULT 'entity' COMMENT 'The entity type for statistics.',
'send_method' set('mail','smtp') NOT NULL DEFAULT '' COMMENT 'Message is sent using PHP mail() or SMTP.',
'from_email' varchar(255) NOT NULL COMMENT 'Sets the From email address for the message',
'from_name' varchar(255) NOT NULL COMMENT 'Sets the From name of the message',
'smtp_host' varchar(255) NOT NULL COMMENT 'Sets the SMTP hosts. All hosts must be separated by a semicolon. You can also specify a different port for each host by using this format: [hostname:port] (e.g. "smtp1.example.com:25;smtp2.example.com"). Hosts will be tried in order.',
'smtp_port' int(4) NOT NULL DEFAULT '25' COMMENT 'Sets the default SMTP server port.',
'smtp_auth' tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Sets SMTP authentication. Utilizes the Username and Password variables.',
'smtp_secure' enum('','ssl','tls','starttls') NOT NULL DEFAULT '' COMMENT 'Sets connection prefix.',
'smtp_username' varchar(255) NOT NULL COMMENT 'Sets SMTP username.',
'smtp_password' varchar(255) NOT NULL COMMENT 'Sets SMTP password.',
'recipient_mail' varchar(255) NOT NULL,
'recipient_name' varchar(255) NOT NULL,
'attachment' varchar(255) NOT NULL,
'content_type' varchar(50) NOT NULL,
'priority' enum('1','3','5') NOT NULL DEFAULT '3' COMMENT 'Email priority (1 = High, 3 = Normal, 5 = low)',
'charset' enum('iso-8859-1','utf-8','windows-1252') NOT NULL DEFAULT 'utf-8' COMMENT 'Sets the CharSet of the message.',
'send_date' timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY ('id'),
KEY 'newsletter_id' ('newsletter_id'),
KEY 'entity_id' ('entity_id'),
KEY 'entity_type' ('entity_type')
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
With a table like this, you have a function that adds emails to queue and your send function will only send X emails every X minutes. This way you will definitely solve memory problems now or in the future when your CRON runs to send emails.