4

Possible Duplicate:
Sending mass email using PHP

I have a PHP script that sends an individual email to all users in my DB, such as a monthly / weekly newsletter.

The code I am using goes as follows:

$subject = $_POST['subject'];
$message = $_POST['message'];

// Get all the mailing list subscribers.
$query = $db->prepare("SELECT * FROM maildb");
$query->execute();

// Loop through all susbcribers, and send and individual email.
foreach ($query as $row) {

    // Setting maximum time limit to infinite.
    set_time_limit(0);

    $newMessage = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
        </head>
        <body>';

    // Search for the [unsubscribe] tag and replace it with a URL for the user to unsubscribe
    $newMessage .= str_replace("[unsubscribe]", "<a href='".BASE_URL."unsubscribe/".$row['hash']."/".$row['email']."'>unsubscribe</a>", $message);

    $newMessage .= '</body></html>';

    $to = $row['email'];

    // Establish content headers
    $headers = "From: info@domain.com"."\n";
    $headers .= "Reply-To: bounce@domain.com"."\n";
    $headers .= "X-Mailer: PHP v.". phpversion()."\n";
    $headers .= "MIME-Version: 1.0"."\n";  
    $headers .= "Content-Type: text/html; charset=iso-8859-1"."\n";
    $headers .= "Content-Transfer-Encoding: 8bit;";

    mail($to, $subject, $newMessage, $headers); // Send email to each individual user

}

This code works perfectly with a REALLY small database... I recently populated my test db with 200k+ users, and obviously this script fails, gets out of memory, and dies...

I know this is a bad way to send so many emails, thats why I'd like to ask you for much more efficient ways to do this!

Thank you very much!

Community
  • 1
  • 1
qalbiol
  • 475
  • 7
  • 21
  • 1
    First thing to do: ditch mail() like the toxic piece of crap it is, and switch to a real mail package, e.g. [Swiftmailer](http://swiftmailer.org) or [PHPMailer](http://phpmailer.worxware.com) – Marc B Sep 02 '12 at 16:31

5 Answers5

2

The timeout you experience is because of the Apache and PHP execution limits.

You need to run it as a CLI application with set_time_limit(0);

php /path/to/app/script.php something like this straight in the console.

If you do not have SSH access then run it with shell_exec like this:

shell_exec("php /path/to/app/script.php > /dev/null 2>/dev/null &");

This will ensure that the script that calls it does not hang around till it finishes.

transilvlad
  • 13,974
  • 13
  • 45
  • 80
1

You can set up a Cron scheduler to run every minute or some interval. Every execution of script will pick few records from database and deletes them from db or set as inactive. Send mail to a small chunk and let the script die. Another cron call will pick few other records and dies. Also you can take advantage of exec().

1

Do them in batches so you only send a few at a time, have a field in your database that checks whether or not they've been sent the newsletter for that month and check it off when the newsletter has been sent to that user, then you can just keep running the script until it's been sent to everyone.

0

I'd rather implode the users in to a variable and send the email in one go

$to_array = array();

foreach ($query as $row) {

  $to_array[] = $row['email'];

}

$to = implode(', ', $to_array);

//do your email stuff here

 mail($to, $subject, $newMessage, $headers); // Send email to all users at once

hope this helps :-)

mithilatw
  • 908
  • 1
  • 10
  • 29
  • 1
    If you are stuck in execution time problem, add this bit of code too.. `ini_set('max_execution_time', 3000);` where in this case 3000 is number of seconds i.e. 5 minutes – mithilatw Sep 02 '12 at 16:36
0

See this Url:--

Sending mass email using PHP

First off, using the mail() function that comes with PHP is not an optimal solution. It is easily marked as spammed, and you need to set up header to ensure that you are sending HTML emails correctly. As for whether the code snippet will work, it would, but I doubt you will get HTML code inside it correctly without specifying extra headers

I'll suggest you take a look at SwiftMailer, which has HTML support, support for different mime types and SMTP authentication (which is less likely to mark your mail as spam).

Community
  • 1
  • 1
Abid Hussain
  • 7,724
  • 3
  • 35
  • 53
  • See this URL It is very use full to you http://stackoverflow.com/questions/1118154/sending-mass-email-using-php – Abid Hussain Sep 02 '12 at 16:30
  • see also http://stackoverflow.com/questions/5179168/php-sending-huge-quantity-of-emails-in-batch – Abid Hussain Sep 02 '12 at 16:31
  • Thanks for your answer, I'll read the articles. SwiftMailer also gets stuck... Maximum execution time of 30 seconds exceeded in /home/content/lib/classes/Swift/Mime/Headers/MailboxHeader.php on line 307 – qalbiol Sep 02 '12 at 16:32
  • you can increase Maximum execution limit ini_set('memory_limit', '1024M'); – Abid Hussain Sep 02 '12 at 16:42