Re: limiting the amount of emails sent at a time in a batch send

From: Date: Thu, 31 Jul 2008 20:24:09 +0000
Subject: Re: limiting the amount of emails sent at a time in a batch send
References: 1 2 3  Groups: php.general 
Request: Send a blank email to php-general+get-277568@lists.php.net to get a copy of this message
Andrew Ballard wrote:
On Thu, Jul 31, 2008 at 1:27 PM, brian <php@logi.ca> wrote:
Richard Kurth wrote:
I want to limit these script two send 100 email and then pause for a few seconds and then send another 100 emails and repeat this tell it has sent all the emails that are dated for today. This script is runs by cron so it is running in the background. How would I do this and is it the best way to do it. I am using swift mailer to send the mail. I think I would use limit 100 in the query but how would I tell it to get the next 100.
There's no need to limit the DB query, nor to track what's been sent by updating the DB. Grab all of the addresses at once and let SwiftMailer deal with the throttling: require('Swift/lib/Swift.php'); require('Swift/lib/Swift/Connection/SMTP.php'); /* this handles the throttling */ require('Swift/lib/Swift/Plugin/AntiFlood.php'); /* this holds all of your addresses */ $recipients = new Swift_RecipientList(); /* Grab the addresses from the DB (this is using MDB2) */ $result = ... while ($row = $result->fetchRow()) {
       $recipients->addTo($row['address'], $row['name']);
} @$result->free(); try {
       $swift = new Swift(new Swift_Connection_SMTP('localhost'),
'your_domain');
       set_time_limit(0);
       $swift->log->enable();
       /* 100 mails per batch with a 60 second pause between batches
        */
       $swift->attachPlugin(new Swift_Plugin_AntiFlood(100, 60),
'anti-flood');
       flush();
       $message = new Swift_Message('your subject');
       $message->setCharset('utf-8');
       $message->setReplyTo(...);
       $message->setReturnPath(...);
       $message->headers->set('Errors-To', ...);
       $message->attach(new Swift_Message_Part($plain_content));
       $message->attach(new Swift_Message_Part($html_content, 'text/html'));
       $num_sent = $swift->batchSend($message, $recipients, new
Swift_Address(..., '...'));
       $swift->disconnect();
... This is a rough example taken from my own script. This would need to be modified if you're not sending the same message to all recipients, of course. It's not clear to me from your example. b
Nice! I'll have to look into this library some time. How do you control it to prevent sending the same message though?
I'm not sure about that. Mine is for a newsletter (not personalised) so Swift just needs a list of addresses. I can't remember if AntiFlood can be used for many unique mails. I suspect that it doesn't.
I can't imagine this is called from a web page, because I'm guessing it would take a few minutes to finish.
cron. But, if you wanted it fired from an admin page (I can't imagine a good situation where something like this would be public) you could add ignore_user_abort() and then jazz up the page with some async JS. If it's called from a cron job, don't you still
have to somehow flag the message as having been delivered so that the next process doesn't come along and send the same thing all over again?
Yeah, I just twigged to the fact that your messages are stored in the database. This is some kind of messaging system? As opposed to a newsletter-type thing, I mean. As above, I don't know that AntiFlood is what you want. That's meant for multiple-recipient mails. There's also a Throttler plugin, though, again, it's meant for batches. You might also look at the IMAP functions. Instead of storing the messages in the DB, you can let the MTA deal with pushing them out and cut Swift (and the cro0n job) out of the loop. b

« previous php.general (#277568) next »