PHPMailer设置个别电子邮件时发送空的收件人字段

3
使用PHPMailer向收件人发送单独邮件时,如果我在代码中添加$mail->SingleTo = TRUE;,则To:字段中将没有任何内容。
当我删除$mail->SingleTo = TRUE;时,我会收到一个在To:字段中正确显示电子邮件地址的邮件。
这是我得到的结果:
reply-to     xxxxxx <xxxx@xxxx.com>, No Reply <no-reply@no-reply.com>
to    
date         Mon, Mar 21, 2011 at 5:07 PM  
subject      Testing    
mailed-by    gmail.com 
signed-by    gmail.com

(其中 xxxxxxx 代表我的电子邮件地址。)

这是我的代码:

if(isset($_POST['submit']))
{
    require_once('PHPMailer_v5.1/class.phpmailer.php');


$mail         = new PHPMailer();

$subject = $_POST['subject'];
$body    = $_POST['emailbody'];
$to         = $_POST['to'];



$mail->IsSMTP(); // telling the class to use SMTP
//$mail->Host       = "localhost"; // SMTP server
$mail->SMTPDebug  = 2;                     // enables SMTP debug information (for testing)
                                           // 1 = errors and messages
                                           // 2 = messages only
$mail->SMTPAuth   = true;                  // enable SMTP authentication
$mail->SMTPSecure = "SSL";                 // sets the prefix to the servier
$mail->Host       = "smtp.gmail.com";      // sets GMAIL as the SMTP server
$mail->Port       = 587;                   // set the SMTP port for the GMAIL server
$mail->Username   = "xxxxxxxxxx@gmail.com";  // GMAIL username
$mail->Password   = "*********";            // GMAIL password

$mail->SetFrom('xxx@xxx.com', 'XXXXXX');

$mail->AddReplyTo("no-reply@xxxxx.com","No Reply");

$mail->Subject    = $subject;

// After adding this line I'm getting an empty To: field 
$mail->SingleTo   = TRUE;

$mail->AddAddress("address1@xxxxxx.com", 'xyz abc');
$mail->AddAddress("address2@xxxxxx.com", 'abc xyz');
//$mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test

$mail->MsgHTML($body);


if(!$mail->Send()) {
  $message= "Mailer Error: " . $mail->ErrorInfo;
}
else
{
  $message= "Message sent!";
}       
}

问题已被接受,但悬赏仍然开放?我们能否知道原因,以便回答悬赏问题? - Kevin Peno
5个回答

3
您正在使用SMTP发送电子邮件。当使用SMTP发送时,phpmailer类未使用SingleTo参数。
此外,如果您查看CreateHeader函数,当SingleTo == true时,收件人仅添加到$this->SingleToArray而不是头本身,因此基本上是PHPmailer的错误。
除非您想修补phpmailer,否则似乎唯一的选择是逐个发送电子邮件,而不使用SingleTo属性。
解决方案将是:
function & prepare_mailer($subject, $body) {

    $mail         = new PHPMailer();
    $mail->IsSMTP(); // telling the class to use SMTP
    //$mail->Host       = "localhost"; // SMTP server
    $mail->SMTPDebug  = 2;                     // enables SMTP debug information (for testing)
                                               // 1 = errors and messages
                                               // 2 = messages only
    $mail->SMTPAuth   = true;                  // enable SMTP authentication
    $mail->SMTPSecure = "SSL";                 // sets the prefix to the servier
    $mail->Host       = "smtp.gmail.com";      // sets GMAIL as the SMTP server
    $mail->Port       = 587;                   // set the SMTP port for the GMAIL server
    $mail->Username   = "xxxxxxxxxx@gmail.com";  // GMAIL username
    $mail->Password   = "*********";            // GMAIL password
    $mail->SetFrom('xxx@xxx.com', 'XXXXXX');
    $mail->AddReplyTo("no-reply@xxxxx.com","No Reply");
    $mail->Subject    = $subject;
    $mail->MsgHTML($body);
    return $mail;
}

foreach( $_POST['to'] as $to ){
    $mail = null;
    $mail = & prepare_mailer($_POST['subject'],$_POST['body']);
    $mail->AddAddress($to['address'], $to['name']);
    $mail->Send();

}

谢谢。如果问题是由SMTP引起的,那么如果我使用此类的邮件功能,我可以按照自己的意愿发送电子邮件吗? - mysterious
如果您不使用SMTP,那么是的,您将需要使用IsMail()并在服务器上配置邮件(来自PHP)。例如:mailsendmail - Szymon Lukaszczyk
我认为,除非在循环内的每个 $mail-Send() 后执行 $mail->ClearAddresses();,否则该代码片段不会将一个地址发送到 To: 字段,因为 AddAddress 会将收件人附加到数组中。 - rkulla
@SzymonLukaszczyk - 感谢您的回复。请查看我的回复,了解SingleTo的未来计划。 - Maxim Masiutin

3

设置所有其他参数,然后在循环中设置收件人、发送电子邮件,最后使用ClearAllRecipients()函数。如下所示:

{  // loop start
        $mail->AddAddress($person_email, $person_name);
        $mail->Send();
        $mail->ClearAllRecipients();
}  // loop end

0
问题出在SmtpSend函数中(在class.phpmailer.php的第701行开始)。正如您在那里看到的,他们没有考虑singleTo设置,只是添加所有收件人并一次发送消息正文。
因此,您应该在那里添加一些逻辑来测试singleTo是否为true,如果是,则修改代码以单独发送这些邮件,并将To:标题添加到消息正文前缀。如果singleTo为false,则可以按原样调用代码(第713-758行)。
或者,如果您不想打补丁,那么您可以使用支持singleTo参数的传输方法(即sendmail)。

我能否使用PHP Mailer的邮件功能选项而不是SMTP来自由发送邮件? - mysterious

0

SingleTo 不是一个好主意。它只适用于 "sendmail" 或 "mail" 传输,而不适用于 SMTP。如果您在 SMTP 中使用 SingleTo,此参数将被忽略,没有任何错误或警告,并且您可能会得到重复的邮件。

由于您在代码中同时使用了 SingleTo 和 SMTP,所以在您的情况下,SingleTo 被忽略了。

SMTP 协议设计的方式是您不能将一条消息发送给多个不同的收件人,每个收件人在 TO: 字段中只有自己的地址。为了让每个收件人在 TO: 中只有自己的名称,整个消息必须再次传输。这就解释了为什么 SingleTo 与 SMTP 不兼容。

根据 PHPMailer 库的作者,SingleTo 计划在 PHPMailer 6.0 发布时弃用,并在 7.0 中删除。作者已经解释说,更好的方法是在更高的级别控制向多个收件人发送电子邮件,因为 PHPMailer 不是邮件列表发送器。他们告诉我们需要避免使用 PHP mail() 函数,因为它非常难以安全地使用;SMTP 更快、更安全,提供更多的控制和反馈。由于 SMTP 与 SingleTo 不兼容,PHPMailer 的作者将删除 SingleTo,而不是 SMTP。


0

$mail->AddAddress() 不支持 CSV 文件 如果你有:

$Emails="addr1@host.com,addr2@host.net"; #etc;

在分割后进行for循环:

$NewList = preg_split("/,/",$Emails);
foreach ($NewList as $k=>$email){
 if ($k==0) $mail->AddAddress($email);  # Add main to the "To" list.
 else  $mail->AddCC($email); # The REST to CC or BCC which ever you prefer.
}

-- BF。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接