Best way to loop through results array to send multiple mail

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Best way to loop through results array to send multiple mail

Post by matthijs »

I have some questions about a script I am making to send a newsletter to a list of people. I posted a similar question here, but as I've understood now it's better to start a new thread instead of hijacking an existing thread.

What I would like to know is:

1 - what is the best way to loop through the results I get from the db? In my first example I first build a multidimensional array and then split it using array_chunk(). I have a feeling that that is a bit laborious, compared to the second example.

2 - when should I implement a delay with sleep()? From what I know, using the phpmailer class I should be able to send quite a lot of emails before the script runs out of time. So, what are your guesses. Can I run the script for less then 1000 mails without a sleep() build in?

3- If needed, what is the best way to implement a delay? Assuming I try to do it in the script itself, and not use a cron job (which many would advice).

Version 1:

Code: Select all

<?php
set_time_limit(300); // 5 minutes

if(isset($_POST['submit']))
{
    //  validation of $_post values here....
    // Setup body here ...
    // instantiate the class here ...
        
    // Get the user's Email
    $sql = 'SELECT FirstName,LastName,EmailAddress,MailType FROM mymaillist_subscribers';
    $result = $db->query($sql); // create MySQLResult object. I use a MySQL class from the php anthology books
    
    $mails = array();
    while ($rows = $result->fetch()) {
       $mails[] = $rows;
    }
    $chunks = array_chunk($mails, 50);

    foreach($chunks as $value)
    {
        foreach($value as $row)
        {
         // Send the emails in this loop.
         $member_name = $row['FirstName'] .$row['LastName'];
         $member_address = $row['emailaddress'];
		  		  
         $mailer->AddAddress($member_address);
 
         $mailer->Body = str_replace('{MEMBER_NAME}', $member_name, $htmlBody);
         $mailer->IsHTML(true);
         $mailer->AltBody = str_replace('{MEMBER_NAME}', $member_name, $textBody);
	
         $mailer->Send();
         $mailer->ClearAddresses();
         $mailer->ClearAttachments();
         $mailer->IsHTML(false);
         echo "Mail sent to: $member_name<br />";
        }

        // Have the loop sleep a few secs
        sleep(3);
    }
}
?>
or

Code: Select all

<?php

...
    $x = 1;
    $hold = 50;

   while($row = $result->fetch())
    {
      // Send the emails in this loop.
      $member_name = $row['name'];
      $member_address = $row['emailaddress'];
		  		  
      $mailer->AddAddress($member_address);
        
      $mailer->Body = str_replace('{MEMBER_NAME}', $member_name, $htmlBody);
      $mailer->IsHTML(true);
      $mailer->AltBody = str_replace('{MEMBER_NAME}', $member_name, $textBody);
		  
      $mailer->Send();
      $mailer->ClearAddresses();
      $mailer->ClearAttachments();
      $mailer->IsHTML(false);
      echo "Mail sent to: $member_name<br />";
      
       // delay method:
      $x++;
      if($x == $hold)
      {  // When $x is equal to $hold, a 3 sec delay will occur avoiding php to timeout
          sleep(3);
          $x = 0;
      }
    }
...

?>
I hope my questions are clear enough.

Thanks, Matthijs
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

I'd say the best way to loop through anything is the most direct method. I'm implying that that is the method with the least overhead.

As for the delay and all that jazz, I would strongly suggest you put it in a chron job. I don't see the point in doing it any other way. At least the time constraints become a non-issue. Just do a set_time_limit(0) and let it run as long as it takes. No need for a delay (it appears) so don't include one.

Cheers
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

Ok, so what I thought already, that the loop in the second version is the most direct and better method because it has the least overhead. Thanks for your input.
As for the delay and all that jazz, I would strongly suggest you put it in a chron job
I've never worked with cron jobs before, so that's still all unknown territory for me unfortunately..

But I'll look into it.
No need for a delay (it appears) so don't include one.
I'll ditch the sleep then. It's just that I have found many solutions using this. Maybe it's used to lessen the burden on the mailserver a bit?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

Sleep is used in bulk mail sending loops to prevent the MTA (mail transfer agent, your mail server) from getting overloaded. Sleep will not prevent php to timeout (though the time the process slept does not count when checking whether the process is timed out).

Memory usage of the first snippet is about three times higher comparing to the second one.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

matthijs wrote:
As for the delay and all that jazz, I would strongly suggest you put it in a chron job
I've never worked with cron jobs before, so that's still all unknown territory for me unfortunately..

But I'll look into it.
It's really not that difficult at all. If you can read and write code, you'll have no problems with cron jobs. :)

It appears that Weirdan has good intel on the sleep function usage in the bulk mailers. In that case, I'd put it back in.

Sorry... :oops:
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

'It appears that Weirdan has good intel on the sleep function usage in the bulk mailers.', wow, what a super-polite method to call me a spammer :)

j/k, no offence taken.
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

'It appears that Weirdan has good intel on the sleep function usage in the bulk mailers.', wow, what a super-polite method to call me a spammer Smile
Ha! Advice directly from someone with loads of experience with mailing lots of people, great! ;)

I'll trust him on this one then and put in the sleep() for now. At least untill I've upped my knowledge on crons and use that.

And I'll certainly go with the second, simpler loop.

Thanks a lot guys!
Post Reply