0

Programmatically speaking, what would be a simple and straightforward way of spacing out the sending of bulk email while avoiding a PHP timeout? This is for contacting a few thousand members belonging to a site.

P.S: Thinking along the terms of splitting up sends into N numbers of email addresses and having a script somehow call itself.

James P.
  • 19,313
  • 27
  • 97
  • 155
  • 1
    I would just go through a third party service. – Jim May 27 '11 at 15:40
  • Slighly off topic, but if this is something you plan on repeatedly, you might look at commercial solutions for sending bulk emails. You run the risk of being marked as a spammer if you aren't careful. – Greg May 27 '11 at 15:42

3 Answers3

2

Easiest way would be just to sleep for some seconds after every x number of emails sent:

$count = 0
while (foo) {
    send_email();
    if ($count++ == 100) {
        sleep(10);//sleep for 10 seconds
        $count = 0;
    }
}
Dan Simon
  • 12,891
  • 3
  • 49
  • 55
  • This won't avoid a PHP timeout, though. It'd probably encourage it by wasting time sleeping instead of spending it mailing. – Marc B May 27 '11 at 15:42
  • @Marc: Not exactly true, time spent sleeping does not contribute to a script's execution time. Of course the script will take much longer to run and I agree that there are certainly more efficient ways to accomplish the goal, but the OP asked for a simple and straightforward solution. – Dan Simon May 27 '11 at 15:52
  • I might give this a try. The reason I want a simple and straightforward solution is to get something running as soon as possible. Afterwards I can have a look at improvements. Another route I'm exploring is using Ajax to call a page and send emails out by blocks of 50 emails or so. – James P. May 28 '11 at 04:05
  • be careful that on Windows server sleep time is counted in execution time [ref. http://stackoverflow.com/questions/740954/php-does-sleep-time-count-for-execution-time-limit/740959#740959], but obviously if you use Windows server you deserve the worst ;) – Marco Demaio Jun 22 '11 at 10:55
1

You can always try the sleep command or manually staggered cronjobs but a better option may be looking into an established library that handles details for you: PEAR Mail_Queue

The Mail_Queue class puts mails in a temporary container, waiting to be fed to the MTA (Mail Transport Agent), and sends them later (e.g. a certain amount of mails every few minutes) by crontab or in other way.

There are also many companies that will handle all of this for you at a price, if that's an option for you.

webbiedave
  • 48,414
  • 8
  • 88
  • 101
  • Going with a third party isn't an option. PEAR looks interesting. I hope it supports the PHP mail function as there isn't SMTP (disabled by the host). – James P. May 28 '11 at 04:12
1

If you are sending to everyone subscribed to the site, you could do the following:

  1. Add a column (if it doesn't already exist) on the user table, something like 'email_sent' and default to 1 (for yes)
  2. When you execute your email send trigger, update all user records setting the 'email_sent' flag to 0 (for no).
  3. Set up a cron job that executes a PHP script (or even hits your web server using a designated page to execute the script) that then selects the first N users that have 'email_sent' set to 0, send them emails, and update the 'email_sent' column to 1 for each that succeeds.

If you're handling multiple mailings, you would need to join across another table that maintains the user:mailout relationship and 'email_sent' status.

arpieb
  • 340
  • 3
  • 7