Hello gtraxx,
I was encountering the same problem with sendings of over 20'000 emails. Below is an extract of my code, that allowed me to send over 100'000 mails without crash.
1) I get all the contact's informations from the database in one single query, and at each row I save the information serialized in a file. This gives us something like :
Code: Select all
$filePath = 'the/path/for/my/File.txt';
// We get the information from the database
$res = mysql_query("SELECT DISTINCT email, other, fields... FROM contacts WHERE ...");
// We make a loop on the contacts
while (false !== ($contactInfo= mysql_fetch_assoc($res))) {
// We put 'em in the file, each line containing the serialized datas of one contact
file_put_contents($filePath, serialize(&$contactInfo)."\n", FILE_APPEND);
}
2) I make a loop on the file, until I get to the end and inside it, I select a range of contacts to do the sending :
Code: Select all
// Number of contacts to manage at a time
$rangeContacts = 1000;
// We create a pointer to the file in read mode
$fileHandler = fopen($filePath, 'r');
// We read the file until we get to the end
while (false === feof($fileHandler)) {
// We loop on the range of contacts to manage
for ($i = 0; $i <= $rangeContacts; $i++) {
/**
* We get the array of datas of the contact and remove the "\n"
*
* @internal The "fgets" function reads *only* the part of the file we ask, so there's no risks of
* PHP Fatal Error "Allowed memory exceeded" if $contactsRange is small enough.
*/
$contactInfo = unserialize(trim(fgets($fileHandler), '0x0A'));
// We put the datas in an array for SwiftMailer
if (is_array($contactInfo)) $swiftRecipients[] = $contactInfo['email'];
// Optimisation
$contactInfo = null;
}
// We add the emails in Swift and make the sending
$message->setTo(&$swiftRecipients);
$swiftMailer->batchSend($message);
}
// We remove the pointer, the variable and the file
fclose($fileHandler);
$fileHandler = null;
unlink($filePath);
And if you want some simple advice for optimisation:
- Use references everywhere you can for arrays / objects (like in "$message->setTo(&$swiftRecipients);")
- Set to null all the variables you don't need anymore in your script (like the "$fileHandler = null;" at the end), it will clear them from memory
- Do only what you really need to do, and try to do them out of the loops
Hope it will help ya or others.
gnutix