PHPMailer不会将所有电子邮件发送到上一个电子邮件地址

时间:2019-11-23 20:19:09

标签: php phpmailer

我正在使用PHPMailer发送电子邮件。我创建了一个功能,可以将3封电子邮件发送到3个不同的电子邮件地址(共发送9封电子邮件)。

  • 第一个电子邮件地址正在接收全部3封电子邮件。
  • 第二个电子邮件地址收到2封电子邮件。
  • 第三个电子邮件地址仅收到1封电子邮件。

为什么会这样?

这是我的代码:

use PHPMailer\PHPMailer\PHPMailer; 
use PHPMailer\PHPMailer\Exception;

require 'lib/phpmailer/vendor/autoload.php'; 

$mail = new PHPMailer(true);

$mail1 = phpmaileremail($reciever1, $usertype1, $file, $subject1, $body1);
$mail2 = phpmaileremail($reciever2, $usertype2, $file, $subject2, $body2);
$mail3 = phpmaileremail($reciever3, $usertype3, $file, $subject3, $body3);

function phpmaileremail($reciever,$usertype, $file, $subject, $body)
{
    global $mail;
    $mail->SMTPDebug = 0;                                        
    $mail->isSMTP();
    $mail->Host = 'smtp.gmail.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'xxx@gmail.com';
    $mail->Password = 'xxx';
    $mail->SMTPSecure = 'tls';                               
    $mail->Port = 587;   

    $mail->setFrom('xxx', 'xxx');            
    $mail->addAddress($reciever); 
    $mail->addAddress($reciever, $usertype); 

    $mail->addAttachment($file);

    $mail->isHTML(true);                                   
    $mail->Subject = $subject; 
    $mail->Body = $body; 
    $mail->AltBody = 'NA'; 
    $mail->send();

    echo "Mail sent";
}

2 个答案:

答案 0 :(得分:2)

因为您正在将$mail对象重用于addAddress()send()。因此,当您第一次致电phpmaileremail()时,第一个地址就会收到电子邮件。然后,当您第二次调用它时,将添加第二个地址,第一个和第二个地址将收到电子邮件。依此类推。

一个简单的解决方案是在$mail函数内部创建phpmaileremail()对象:

function phpmaileremail($reciever,$usertype, $file, $emailsubject, $email_body )
{

  $mail = new PHPMailer(true);

  $mail->SMTPDebug = 0;                                        
  $mail->isSMTP();                                             
  $mail->Host       = 'smtp.gmail.com;';                     
  $mail->SMTPAuth   = true;                              
  $mail->Username   = 'XXXXXXXX@gmail.com';                  
  $mail->Password   = 'XXXXXXXXXXXXXXXXXX';                         
  $mail->SMTPSecure = 'tls';                               
  $mail->Port       = 587;   

  $mail->setFrom('XXXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXX');            
  $mail->addAddress($reciever); 
  $mail->addAddress($reciever, $usertype); 
  // Attachments
  $mail->addAttachment($file);         // Add attachments

  $mail->isHTML(true);                                   
  $mail->Subject = $emailsubject; 
  $mail->Body    = $email_body; 
  $mail->AltBody = 'NA'; 
  $mail->send(); 

  echo "Mail sent"; 

}

PS:没关系,但是reciever被写为receiver。我也犯了那个错误。

答案 1 :(得分:1)

Kiko的答案会起作用,但这不是最好的方法。顾名思义,addAddress 添加地址,它不是绝对设置的地址,也不是替换您已经添加的现有收件人的地址。

PHPMailer具有清除要结束的地址列表的标准功能,称为clearAddresses,因此正确的方法是在每条消息发送后调用该地址,并在发送下一个地址之前添加新地址,因此顺序大致如下:

addAddress();
send();
clearAddresses();
addAddress();
send();

,依此类推。 the mailing list example provided with PHPMailer最清楚地展示了这一点,它循环发送,每次都调用clearAddresses

您每次都可以使用新的PHPMailer实例来实现相同的目的(这具有清除地址的作用,但也可以清除所有其他内容),但是重用该实例更为有效。如果要通过SMTP发送(这是事实),尤其如此,因为它将允许您使用keepalive,从而大大减少了建立SMTP连接的开销。如果使用新实例,则每次都会删除并重新创建连接。您可以通过使PHPMailer实例为静态来实现此功能:

function phpmaileremail($reciever, $usertype, $file, $emailsubject, $email_body)
{
    static $mail;

    if ($mail === null) {
        //Set everything that remains the same all the time in here
        $mail = new PHPMailer();
        $mail->SMTPDebug = 0;
        $mail->isSMTP();
        $mail->Host = 'smtp.gmail.com;';
        $mail->SMTPAuth = true;
        $mail->Username = 'XXXXXXXX@gmail.com';
        $mail->Password = 'XXXXXXXXXXXXXXXXXX';
        $mail->SMTPSecure = 'tls';
        $mail->Port = 587;
        $mail->SMTPKeepAlive = true;
        $mail->setFrom('XXXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXX');
    }
    $mail->addAddress($reciever, $usertype);
    // Attachments
    $mail->addAttachment($file);         // Add attachments

    $mail->isHTML(true);
    $mail->Subject = $emailsubject;
    $mail->Body = $email_body;
    $mail->AltBody = 'NA';
    $mail->send();
    $mail->clearAddresses();
    $mail->clearAttachments();
    echo "Mail sent";
}

这具有不使用全局变量的额外好处。还要注意使用clearAttachments,因为它的工作方式与地址相同。