Jump to content

Sending Mass Html E-Mail


DizzyDan

Recommended Posts

Been a little bit since I needed help BUT now i do so im back! I have been sending e-mails for clients via, Mail-dog or Constant Contact. My question is what if i want to send it myself, how the heck can i send an HTML e-mail without the use of a third party. Objective: Create HTML e-mail and send to a big list of e-mails with out paying a company to mail it for me or without a company mailing it for free with there lame logo on it. I hope i explained it well enough!.

Link to comment
Share on other sites

I use the PEAR Mail Queue package. "Sending" the emails just queues everything up in a database, and then I have a script run every minute via a cron job to send a certain number of emails. On our server I have it sending batches of 1000 at a time. It's easy to screw that up, so here's a tip: when you run a script via a command line (e.g., a cron job), the PHP execution time limit does not apply. I thought that if I set the script to run every minute, and set the timeout in the script to 1 minute, that it would process as many emails as it can in a minute, would quit because of the time limit, and then the next run would start processing wherever it left off. That does not happen, the time limit doesn't apply so the script never times out. It turns out it takes a lot longer than a minute to send 1000 emails, so what was happening is it would start sending the first 1000 emails, and maybe it gets through 100 in a minute and then the next cron job starts. So that cron job grabs the next 1000 emails, but 900 of those emails are being processed by the other script still. So people ended up getting 20 or 30 duplicate emails under heavy traffic. So, my first thought was to use a text file that just contains "true" if mails are currently being processed, and "false" if not. When the script runs it checks the file, and if it's "true" then the script just quits. If it's "false" then it sets the file contents to "true" and starts processing emails. That works fine, until the script dies from a fatal error for whatever reason and now the file is stuck at "true" so emails don't go out any more. The fix for that is to use PHP's register_shutdown_function to have a function execute whenever the script ends, for any reason, which resets the file back to "false". So even if a fatal error happens it will still set the file back to false so that the next time the email process script runs it starts from wherever the last one left off. This is what that script looks like for this particular application:

<?phprequire_once '../include/global.init.php';require_once 'Mail/Queue.php';$mail_file = $config['lms_root'] . $config['file_upload_rel'] . $config['ds'] . 'mail_check.log';$check = trim(file_get_contents($mail_file));if ($check == 'true') exit();register_shutdown_function('reset_mail_file', $mail_file);file_put_contents($mail_file, 'true');$container_options = array(   'type' => 'db',   'dsn' => 'mysql://' . $config['db_user'] . ':' . $config['db_pass'] . '@' . $config['db_host'] . '/' . $config['db_name'],   'mail_table' => 'mail_queue');$mail_options = array(   'driver' => 'sendmail');$max_mails = 1000;$mail_queue =& new Mail_Queue($container_options, $mail_options);$mail_queue->sendMailsInQueue($max_mails);echo 'done';function reset_mail_file($fname){   file_put_contents($fname, 'false');}?>

Link to comment
Share on other sites

I use the PEAR Mail Queue package. "Sending" the emails just queues everything up in a database, and then I have a script run every minute via a cron job to send a certain number of emails. On our server I have it sending batches of 1000 at a time. It's easy to screw that up, so here's a tip: when you run a script via a command line (e.g., a cron job), the PHP execution time limit does not apply. I thought that if I set the script to run every minute, and set the timeout in the script to 1 minute, that it would process as many emails as it can in a minute, would quit because of the time limit, and then the next run would start processing wherever it left off. That does not happen, the time limit doesn't apply so the script never times out. It turns out it takes a lot longer than a minute to send 1000 emails, so what was happening is it would start sending the first 1000 emails, and maybe it gets through 100 in a minute and then the next cron job starts. So that cron job grabs the next 1000 emails, but 900 of those emails are being processed by the other script still. So people ended up getting 20 or 30 duplicate emails under heavy traffic. So, my first thought was to use a text file that just contains "true" if mails are currently being processed, and "false" if not. When the script runs it checks the file, and if it's "true" then the script just quits. If it's "false" then it sets the file contents to "true" and starts processing emails. That works fine, until the script dies from a fatal error for whatever reason and now the file is stuck at "true" so emails don't go out any more. The fix for that is to use PHP's register_shutdown_function to have a function execute whenever the script ends, for any reason, which resets the file back to "false". So even if a fatal error happens it will still set the file back to false so that the next time the email process script runs it starts from wherever the last one left off. This is what that script looks like for this particular application:
<?php require_once '../include/global.init.php';require_once 'Mail/Queue.php'; $mail_file = $config['lms_root'] . $config['file_upload_rel'] . $config['ds'] . 'mail_check.log';$check = trim(file_get_contents($mail_file)); if ($check == 'true') exit(); register_shutdown_function('reset_mail_file', $mail_file);file_put_contents($mail_file, 'true'); $container_options = array(   'type' => 'db',   'dsn' => 'mysql://' . $config['db_user'] . ':' . $config['db_pass'] . '@' . $config['db_host'] . '/' . $config['db_name'],   'mail_table' => 'mail_queue'); $mail_options = array(   'driver' => 'sendmail'); $max_mails = 1000;$mail_queue =& new Mail_Queue($container_options, $mail_options);$mail_queue->sendMailsInQueue($max_mails); echo 'done'; function reset_mail_file($fname){   file_put_contents($fname, 'false');} ?>

that's bad @$$. I like it.
Link to comment
Share on other sites

If you have questions just post back here. Start by looking into the PEAR Mail and Mail Queue packages. The code I posted is not the code that "sends" (queues) the mails, it's the automated script which looks for mails that have been queued and uses the Mail Queue to send them. The code to queue up the mails looks more like this:

require_once 'Mail/Queue.php';$container_options = array(   'type' => 'db',   'dsn' => 'mysql://' . $config['db_user'] . ':' . $config['db_pass'] . '@' . $config['db_host'] . '/' . $config['db_name'],   'mail_table' => 'mail_queue');$mail_options = array(   'driver' => 'sendmail');$mail_queue =& new Mail_Queue($container_options, $mail_options);if ($subject != '' && $message != ''){   $now = time();   foreach ($users as $user)   {     $nr++;     $to = $user['email'];     $mail =& new Mail_mime();     $mail->setTXTBody($message);     $body = $mail->get();     $headers = $mail->headers(array('From' => $from, 'To' => $to, 'Subject' => $subject));     $ret = $mail_queue->put($from, $to, $headers, $body);   }}

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...