PHPMailer:群发电子邮件 - 一次发送所有可变消息,而不是单独发送

时间:2015-02-03 14:40:06

标签: php email loops variables phpmailer

我目前正试图找出最佳方法。

我所制作的当前系统逐个发送电子邮件,并填写数组中每个条目的信息,例如电子邮件,名字和姓氏。

这里的问题是,如果我发送很多消息,它需要永远运行,因为它每次调用一个函数,而我希望它通过一个函数一次性发送它们。

我知道您可以添加多个,但电子邮件的正文不会发送与每封电子邮件相关的正确信息。如果有人能帮助我,我真的很感激,因为我已经搜遍了所有的解决方案。

<?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();

    }   

}

?>

谢谢

2 个答案:

答案 0 :(得分:4)

与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并使用它来中继 - 它将比直接发送更快,更可靠。

答案 1 :(得分:2)

是的,通过修改代码可以解决问题,问题不在于PHPMailer本身,而在于您的方法。您应该避免在loop内使用该类的新实例(这会导致大型列表的内存耗尽),而只是在$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();

  }  
} 

使用上述方法,我个人已经发送了数十万封电子邮件,但正如他们在评论中所说的那样,您将面临被列入黑名单的风险(您可以查看herehere了解详情)