PHPMailer:大量电子邮件 - 一次发送所有可变消息,而不是单独发送
PHPMailer: Mass Emails - Send all variable messages at once, instead of individually
我目前正在尝试找到执行此操作的最佳方法。
我目前做的系统是一个接一个地发送邮件,并在数组中填写每个条目的信息,例如电子邮件、名字和姓氏。
这里的问题是,如果我发送大量消息,它需要永远 运行 通过,因为它每次都调用一个函数,而不是我希望它通过一个函数一次发送所有消息。
我知道您可以添加多个,但是电子邮件的正文不会发送与每封电子邮件相关的正确信息。如果有人能帮我解决这个问题,我将不胜感激,因为我已经到处寻找解决方案了。
<?php
require '../phpmailer/PHPMailerAutoload.php';?>
<?php
/* Block List */
$blocklist = array('emailblocked@gmail.com', 'emailblocked2@gmail.com');
$emaillist = array(
array(
'Email'=>'example@gmail.com',
'First Name'=>'John',
'Last Name'=>'Doe'
),
array(
'Email'=>'example2@gmail.com',
'First Name'=>'Joe',
'Last Name'=>'Doe'
),
array(
'Email'=>'example3@gmail.com',
'First Name'=>'Jane',
'Last Name'=>'Doe'
),
);
foreach($emaillist as $emailkey){
if (in_array($emailkey['Email'], $blocklist)) {
echo 'Message has been been blocked for '.$emailkey['Email'].'<br>';
}else{
$mail = new PHPMailer;
// $mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.mandrillapp.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'username@example.com'; // SMTP username
$mail->Password = 'passwordgoeshere'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
$mail->From = 'noreply@example.com';
$mail->FromName = 'Example';
$mail->addAddress($emailkey['Email'], $emailkey['First Name'].' '.$emailkey['Last Name']); // Add a recipient
$mail->addReplyTo('info@example.com', 'Information');
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $emailkey['First Name'].' '.$emailkey['Last Name'];
$emailtemp = file_get_contents('templates/temp-1.html');
$emailtempfilteremail = str_replace("[[email]]", $emailkey['Email'], $emailtemp);
$emailtempfilterfirstname = str_replace("[[firstname]]", $emailkey['First Name'], $emailtempfilteremail);
$emailtempfilterlastname = str_replace("[[lastname]]", $emailkey['Last Name'], $emailtempfilterfirstname);
$mail->Body = $emailtempfilterlastname;
$mail->AltBody = 'This is a spicy email!';
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent to '.$emailkey['Email'].'<br>';
}
$mail->ClearAllRecipients();
}
}
?>
谢谢
是的,修改您的代码是可能的,问题不在于 PHPMailer
本身,而在于您的方法。您应该避免在 loop
中使用 class 的新实例(这会导致大列表的内存耗尽),而是仅在 $mail->addAddress(...)
或 $mail->Subject(...)
中调用 foreach
循环。
如果您阅读 PHPMailer
的源代码,您会注意到函数 addAddress()
、Subject()
或 Body()
的工作原理。
您的代码应如下所示:
<?php
/*Move your "generic" initialization outside the loop*/
$mail = new PHPMailer;
// $mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.mandrillapp.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'username@example.com'; // SMTP username
$mail->Password = 'passwordgoeshere'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
$mail->From = 'noreply@example.com';
$mail->FromName = 'Bet Monkey';
$mail->isHTML(true); // Set email format to HTML
$mail->addReplyTo('info@example.com', 'Information');
$emailtemp = file_get_contents('templates/temp-1.html');
$mail->AltBody = 'This is a spicy email!';
/*Start the loop by adding email addresses*/
foreach($emaillist as $emailkey){
if (in_array($emailkey['Email'], $blocklist)) {
echo 'Message has been been blocked for '.$emailkey['Email'].'<br>';
}else{
$mail->addAddress($emailkey['Email'], $emailkey['First Name'].' '.$emailkey['Last Name']); // Add a recipient
$mail->Subject = $emailkey['First Name'].' '.$emailkey['Last Name'];
$emailtempfilteremail = str_replace("[[email]]", $emailkey['Email'], $emailtemp);
$emailtempfilterfirstname = str_replace("[[firstname]]", $emailkey['First Name'], $emailtempfilteremail);
$emailtempfilterlastname = str_replace("[[lastname]]", $emailkey['Last Name'], $emailtempfilterfirstname);
$mail->Body = $emailtempfilterlastname;
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent to '.$emailkey['Email'].'<br>';
}
$mail->ClearAllRecipients();
}
}
使用上述方法,我个人已经发送了数十万封电子邮件,但是,正如他们在评论中所说的那样——您将面临被列入黑名单的风险(您可以查看 here or here 了解详情)。
与 PHPMailer 捆绑在一起的示例中有一个 how to send to a list from a database efficiently 的示例。使用 PHPMailer 发送大量邮件本身不会让您列入黑名单,但您确实需要谨慎行事。 Mandrill 并不神奇 - 如果您通过它发送垃圾邮件,它会像其他任何东西一样容易被阻止。
如果你想从 PHP 同时发送 50 个,使用 pcntl
扩展启动多个进程,但它实际上对你帮助不大,因为你会大大增加开销.您可以在 PHPMailer 中设置 SMTPKeepAlive = true
这将大大减少开销(它避免为每条消息建立新连接),但它仍然不会同时发送消息 - 什么都不会。 SMTP 中没有选项可以在同一连接上同时发送具有不同正文的多封邮件。
在浏览器加载页面期间发送到大列表非常不可靠;使用 cron 脚本或后台进程进行实际发送,只需通过 Web 界面进行设置即可。如果您正在等待页面加载,请注意一个提示 - 尽早调用 ignore_user_abort()
以便在您的浏览器关闭连接时它不会停止发送 - 并注意页面刷新!如果你想发送得更快,安装一个像 postfix 这样的本地邮件服务器并用它来中继——它会比直接发送更快更可靠。
我目前正在尝试找到执行此操作的最佳方法。
我目前做的系统是一个接一个地发送邮件,并在数组中填写每个条目的信息,例如电子邮件、名字和姓氏。
这里的问题是,如果我发送大量消息,它需要永远 运行 通过,因为它每次都调用一个函数,而不是我希望它通过一个函数一次发送所有消息。
我知道您可以添加多个,但是电子邮件的正文不会发送与每封电子邮件相关的正确信息。如果有人能帮我解决这个问题,我将不胜感激,因为我已经到处寻找解决方案了。
<?php
require '../phpmailer/PHPMailerAutoload.php';?>
<?php
/* Block List */
$blocklist = array('emailblocked@gmail.com', 'emailblocked2@gmail.com');
$emaillist = array(
array(
'Email'=>'example@gmail.com',
'First Name'=>'John',
'Last Name'=>'Doe'
),
array(
'Email'=>'example2@gmail.com',
'First Name'=>'Joe',
'Last Name'=>'Doe'
),
array(
'Email'=>'example3@gmail.com',
'First Name'=>'Jane',
'Last Name'=>'Doe'
),
);
foreach($emaillist as $emailkey){
if (in_array($emailkey['Email'], $blocklist)) {
echo 'Message has been been blocked for '.$emailkey['Email'].'<br>';
}else{
$mail = new PHPMailer;
// $mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.mandrillapp.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'username@example.com'; // SMTP username
$mail->Password = 'passwordgoeshere'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
$mail->From = 'noreply@example.com';
$mail->FromName = 'Example';
$mail->addAddress($emailkey['Email'], $emailkey['First Name'].' '.$emailkey['Last Name']); // Add a recipient
$mail->addReplyTo('info@example.com', 'Information');
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $emailkey['First Name'].' '.$emailkey['Last Name'];
$emailtemp = file_get_contents('templates/temp-1.html');
$emailtempfilteremail = str_replace("[[email]]", $emailkey['Email'], $emailtemp);
$emailtempfilterfirstname = str_replace("[[firstname]]", $emailkey['First Name'], $emailtempfilteremail);
$emailtempfilterlastname = str_replace("[[lastname]]", $emailkey['Last Name'], $emailtempfilterfirstname);
$mail->Body = $emailtempfilterlastname;
$mail->AltBody = 'This is a spicy email!';
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent to '.$emailkey['Email'].'<br>';
}
$mail->ClearAllRecipients();
}
}
?>
谢谢
是的,修改您的代码是可能的,问题不在于 PHPMailer
本身,而在于您的方法。您应该避免在 loop
中使用 class 的新实例(这会导致大列表的内存耗尽),而是仅在 $mail->addAddress(...)
或 $mail->Subject(...)
中调用 foreach
循环。
如果您阅读 PHPMailer
的源代码,您会注意到函数 addAddress()
、Subject()
或 Body()
的工作原理。
您的代码应如下所示:
<?php
/*Move your "generic" initialization outside the loop*/
$mail = new PHPMailer;
// $mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.mandrillapp.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'username@example.com'; // SMTP username
$mail->Password = 'passwordgoeshere'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
$mail->From = 'noreply@example.com';
$mail->FromName = 'Bet Monkey';
$mail->isHTML(true); // Set email format to HTML
$mail->addReplyTo('info@example.com', 'Information');
$emailtemp = file_get_contents('templates/temp-1.html');
$mail->AltBody = 'This is a spicy email!';
/*Start the loop by adding email addresses*/
foreach($emaillist as $emailkey){
if (in_array($emailkey['Email'], $blocklist)) {
echo 'Message has been been blocked for '.$emailkey['Email'].'<br>';
}else{
$mail->addAddress($emailkey['Email'], $emailkey['First Name'].' '.$emailkey['Last Name']); // Add a recipient
$mail->Subject = $emailkey['First Name'].' '.$emailkey['Last Name'];
$emailtempfilteremail = str_replace("[[email]]", $emailkey['Email'], $emailtemp);
$emailtempfilterfirstname = str_replace("[[firstname]]", $emailkey['First Name'], $emailtempfilteremail);
$emailtempfilterlastname = str_replace("[[lastname]]", $emailkey['Last Name'], $emailtempfilterfirstname);
$mail->Body = $emailtempfilterlastname;
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent to '.$emailkey['Email'].'<br>';
}
$mail->ClearAllRecipients();
}
}
使用上述方法,我个人已经发送了数十万封电子邮件,但是,正如他们在评论中所说的那样——您将面临被列入黑名单的风险(您可以查看 here or here 了解详情)。
与 PHPMailer 捆绑在一起的示例中有一个 how to send to a list from a database efficiently 的示例。使用 PHPMailer 发送大量邮件本身不会让您列入黑名单,但您确实需要谨慎行事。 Mandrill 并不神奇 - 如果您通过它发送垃圾邮件,它会像其他任何东西一样容易被阻止。
如果你想从 PHP 同时发送 50 个,使用 pcntl
扩展启动多个进程,但它实际上对你帮助不大,因为你会大大增加开销.您可以在 PHPMailer 中设置 SMTPKeepAlive = true
这将大大减少开销(它避免为每条消息建立新连接),但它仍然不会同时发送消息 - 什么都不会。 SMTP 中没有选项可以在同一连接上同时发送具有不同正文的多封邮件。
在浏览器加载页面期间发送到大列表非常不可靠;使用 cron 脚本或后台进程进行实际发送,只需通过 Web 界面进行设置即可。如果您正在等待页面加载,请注意一个提示 - 尽早调用 ignore_user_abort()
以便在您的浏览器关闭连接时它不会停止发送 - 并注意页面刷新!如果你想发送得更快,安装一个像 postfix 这样的本地邮件服务器并用它来中继——它会比直接发送更快更可靠。