Sending multiple mails
Moderator: General Moderators
Sending multiple mails
Hello Friends,
I want to know how to send mails to multiple email addresses using PHP code.
Thanks.
Vishal Gupta
I want to know how to send mails to multiple email addresses using PHP code.
Thanks.
Vishal Gupta
use the CC header (carbon copy), or the BCC (if you do not want the recipients to know it's a mass mailing). this only works if it's the same message to all, if the message changes for each recipient you need to put the recipients in an array and use a foreach loop
Take a look at the examples on this page: http://www.php.net/mail
And then what you do is extract the people who are going to get the mail into an array (see: http://www.php.net/arrays).
And then from the array with the e-mail address, loop through it using foreach() loop (for example, there is other ways).
Then in the loop, use the code on that mail page but replace the value of the recipient with the value from the array.
This is only good for a couple hundred people at the most. Any more and you'll experience very slow loading times. So it's best to split up the sending into chunks if you are sending it to multiple thousands of people.
And then what you do is extract the people who are going to get the mail into an array (see: http://www.php.net/arrays).
And then from the array with the e-mail address, loop through it using foreach() loop (for example, there is other ways).
Then in the loop, use the code on that mail page but replace the value of the recipient with the value from the array.
This is only good for a couple hundred people at the most. Any more and you'll experience very slow loading times. So it's best to split up the sending into chunks if you are sending it to multiple thousands of people.
sami you're too sloooooowwww
anyways just thought I'd add you should put at the top of your script so it can keep on running without timing out, but beware... if you invoke an infinite loop and you have set the time limit to unlimited you will have to restart apache. You can also use a function called array_chunk() for splitting arrays into chunks, of say 50 emails at a time then use the function called sleep() to wait a certain amount of time... say 60 seconds, that way after every 50 mails it fires off it waits for a little while..
as you can see using the BCC is the easiest because it's just one call to mail
anyways just thought I'd add you should put
Code: Select all
set_time_limit(0);as you can see using the BCC is the easiest because it's just one call to mail
jshpro2, how would you use that array_chunk() function?
A solution with the sleep() function I have seen is:
As suggested, sending the mails as bcc: would be faster. But I've also heard that that could give problems with the emails being seen as spam?
Jenk's suggestion "limit the number of emails sent in one chunk in my opinion" also seems like a good one.
Would it be a good idea to place a rule in a loop which changes the value of a field "sent" in the emails table from 0 to 1. Then when the user wants to sent the next (100?) emails the loop skips the email address fields with "sent"value 1, and takes the next 100 with value "sent" 0. I'm just thinking aloud here, don't know if this is a good solution.
A solution with the sleep() function I have seen is:
Code: Select all
$x = 1;
$hold = 50; // quantity of emails sent before 3 sec delay
$emails = mysql_query("SELECT email FROM members");
while ($sendemail = mysql_fetch_array($emails))
{
$email = $sendemail["email"];
mail($email, $subject,
$message, "From:Your name <you@whatever.com>");
$x++;
if($x == $hold)
{ // When $x is equal to $hold, a 3 sec delay will occur avoiding php to timeout
sleep(3);
$x = 0;
}
}Jenk's suggestion "limit the number of emails sent in one chunk in my opinion" also seems like a good one.
Would it be a good idea to place a rule in a loop which changes the value of a field "sent" in the emails table from 0 to 1. Then when the user wants to sent the next (100?) emails the loop skips the email address fields with "sent"value 1, and takes the next 100 with value "sent" 0. I'm just thinking aloud here, don't know if this is a good solution.
- feyd
- Neighborhood Spidermoddy
- Posts: 31559
- Joined: Mon Mar 29, 2004 3:24 pm
- Location: Bothell, Washington, USA
It's highly recommended to not use the mail function for mass mailing, as each call will make a new connection to the smtp server or sendmail, resulting is massive time delay.. Instead use something like phpmailer.
Matt, that solution is semantically the same to the array_chunk, instead of "ticking" X each iteration and waiting till it gets to 50, I just woulda split the array into sub-arrays with 50 elements so I don't have to keep track of $x..
Any reason you don't just put all the emails in the BCC? Or do what feyd said?
Any reason you don't just put all the emails in the BCC? Or do what feyd said?
jshpro2, you're correct. I have taken a look at array_chunk function and it probably easier to use then some x++ loop.
Something like this maybe (comments are welcome!)?
The reason I said BCC might not work that well, is that I've read in some places that emails being sent as bcc: could be recognized as spam easier. But I might be totally wrong here. Please correct me if so.
In fact in the mailingslist script I'm writing I do use phpmailer. However, if I'm understand it correctly: even though the use of phpmailer will make the process of mailing very easy and phpmailer does a lot of the work for you, some sort of loop is still necessary to sent all the emails. At least, that's what I understand from a tutorial on phpfreaks:
http://www.phpfreaks.com/tutorials/130/8.php
Or am I missing some information? Feyd, could you explain why using phpmailer would be better? Does phpmailer not make new connections to the smtp server for each mail?
Something like this maybe (comments are welcome!)?
Code: Select all
// this comes from a db normally
$input_array = array('email1', 'email2', 'email3', 'email4', 'email5', 'email6');
$chunks = array_chunk($input_array, 2);
foreach ($chunks as $key => $value)
{
foreach ($value as $key2 => $email)
{
mail($email, $subject, $message, "From:Your name <you@whatever.com>");
}
sleep(3);
}You mean using phpmailer?Or do what feyd said?
In fact in the mailingslist script I'm writing I do use phpmailer. However, if I'm understand it correctly: even though the use of phpmailer will make the process of mailing very easy and phpmailer does a lot of the work for you, some sort of loop is still necessary to sent all the emails. At least, that's what I understand from a tutorial on phpfreaks:
http://www.phpfreaks.com/tutorials/130/8.php
Code: Select all
// instantiate the class
$mailer = new FreakMailer();
// Get the user's Email
$sql = mysql_query("SELECT FirstName,LastName,EmailAddress,MailType FROM users WHERE 1");
while($row = mysql_fetch_object($sql))
{
// Send the emails in this loop.
$member_name = $row->FirstName;
if(!empty($row->LastName))
{
$member_name .= ' '.$row->LastName;
}
if($row->MailType == 'html')
{
$mailer->Body = str_replace('{MEMBER_NAME}', $member_name, $htmlBody);
$mailer->IsHTML(true);
$mailer->AltBody = str_replace('{MEMBER_NAME}', $member_name, $textBody);
}
else
{
$mailer->Body = str_replace('{MEMBER_NAME}', $member_name, $textBody);
$mailer->isHTML(false);
}
$mailer->Send();
$mailer->ClearAddresses();
$mailer->ClearAttachments();
$mailer->IsHTML(false);
echo "Mail sent to: $member_name<br />";
}I have added a bit of code to my mailinglist script. It uses the phpmailer class to send the mails. The emails and names come from a db. I added the set_time_limit() and sleep() functions in the loop. The loop is broken in chunks using the array_chunk function suggested by jshpro2.
I hope some of you want to take a look at my code. It is meant for a very simple mailinglist script. I don't expect to use it for large amounts of mail, maybe hundreds. From what I understand so far, mailing thousands will be problematic without using a cron job or some other way.
As you can see, in the example above I've set the set_time_limit to 5 minutes. I could change that to a larger value.
Using the array_chunk i split the array coming out of the db in chunks of 10 emails. That could be more (50? 100?).
I sleep for 5 sec in each foreach loop.
Thanks for any feedback!
I hope some of you want to take a look at my code. It is meant for a very simple mailinglist script. I don't expect to use it for large amounts of mail, maybe hundreds. From what I understand so far, mailing thousands will be problematic without using a cron job or some other way.
Code: Select all
<?php
set_time_limit(300); // 5 minutes
if(isset($_POST['submit']))
{
// validation of $_post values here....
/*-------------------------------------------------------
If all is well process the mail
----------------------------------------------------------*/
// Setup body
$textBody = "Dear {MEMBER_NAME},\n\nCheck out PHP Freaks: http://www.phpfreaks.com\n\nSincerely,\nAdmin";
$htmlBody = "Dear {MEMBER_NAME},<br /><br />Check out this <b>html</b> mail from PHP Freaks: http://www.phpfreaks.com<br /><br />Sincerely,<br />Admin";
// instantiate the class
$mailer = new FreakMailer();
$mailer->Subject = 'This is a test';
// 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, 10);
foreach($chunks as $value)
{
foreach($value as $row)
{
// Send the emails in this loop.
$member_firstname = $row['FirstName'];
$member_address = $row['EmailAddress'];
$mailer->AddAddress($member_address);
if(!empty($row['LastName']))
{
$member_name .= ' '.$row['LastName'];
}
if($row['MailType'] == 'html')
{
$mailer->Body = str_replace('{MEMBER_NAME}', $member_name, $htmlBody);
$mailer->IsHTML(true);
$mailer->AltBody = str_replace('{MEMBER_NAME}', $member_name, $textBody);
}
else
{
$mailer->Body = str_replace('{MEMBER_NAME}', $member_name, $textBody);
$mailer->isHTML(false);
}
$mailer->Send();
$mailer->ClearAddresses();
$mailer->ClearAttachments();
$mailer->IsHTML(false);
echo "Mail sent to: $member_name<br />";
}
// Have the loop sleep a few secs
sleep(5);
}
}
?>Using the array_chunk i split the array coming out of the db in chunks of 10 emails. That could be more (50? 100?).
I sleep for 5 sec in each foreach loop.
Thanks for any feedback!