使用phpmailer发送批量邮件

4

我刚接触Phpmailer,现在要用它从noreply账户向一千多人发送批量邮件。当我把邮件发送给一两个人时,代码可以正常工作,但是当我发送给所有人(包括自己)时,邮件会被归为垃圾邮件。还有一个问题是,在邮件的详细信息中,会显示所有收件人的电子邮件地址,而我不希望这样做。

以下是代码:

//date_default_timezone_set('America/Toronto');

require_once('../class.phpmailer.php');
//include("class.smtp.php"); // optional, gets called from within class.phpmailer.php  if not already loaded

$mail = new PHPMailer();
$mail->IsSMTP(); // telling the class to use SMTP
$mail->Host          = "smtp1.site.com;smtp2.site.com";
$mail->SMTPAuth      = true;// enable SMTP authentication
$mail->SMTPKeepAlive = true;// SMTP connection will not close after each email sent
$mail->Host          = "mail.yourdomain.com"; // sets the SMTP server
$mail->Port          = 26;                    // set the SMTP port for the server
$mail->Username      = "yourname@yourdomain"; // SMTP account username
$mail->Password      = "yourpassword";        // SMTP account password
$mail->SetFrom('noreply@mydomain.com', 'List manager');
$mail->AddReplyTo('list@mydomain.com', 'List manager');
$mail->Subject       = 'Newsletter';
$ids = mysql_query($select, $connection) or die(mysql_error());
while ($row = mysql_fetch_row($ids)) {
$mail->AltBody    = "To view the message, please use an HTML compatible email viewer!";
$mail->MsgHTML($body);
$mail->AddAddress($row[0]);
$mail->Send();//Sends the email
}
3个回答

12

正如JoLoCo所指出的,AddAddress()方法只是将一个新的地址添加到现有的收件人列表中。而且由于您正在使用添加/发送循环,因此会发送大量重复副本给第一个收件人,比第二个少一个,依此类推......

您需要的是:

while($row = mysql_fetch_row(...)) {
   $mail->AddAddress($row[0]);
   $mail->send();
   $mail->ClearAllRecipients(); // reset the `To:` list to empty
}

另一方面,由于这会向您的邮件服务器发送大量单独的电子邮件,因此另一个选择是生成一封单个电子邮件,并将所有收件人BCC。

$mail->AddAddress('you@example.com'); // send the mail to yourself
while($row = mysql_fetch_row(...)) {
   $mail->AddBCC($row[0]);
}
$mail->send();

这个选项很可能更可取。您只生成一封电子邮件,让邮件服务器处理将副本发送给每个收件人的重活。


Bcc的问题在于它被当作垃圾邮件发送。我在两三个不同的账户上测试过,所有的邮件都被归类为垃圾邮件。 - user992654
你需要做其他事情,比如实现域密钥和SPF记录,或将邮件发送移到更“合法”的平台上以缓解垃圾邮件问题。但除此之外,只需切换为使用"To:",并知道PHP将必须为每个收件人生成一个电子邮件即可。 - Marc B
感谢您提供这个好的脚本,我通过它得到了清空电子邮件地址的想法:$mail->ClearAllRecipients()。 - thecodedeveloper.com

3

我认为您正在将新地址添加到已发送的电子邮件中,因此第一封电子邮件将发送给一个人,第二封电子邮件将发送给那个人加上另一个人,第三封电子邮件将发送给这两个人以及另外一个人,以此类推。

此外,我不认为您需要每次设置AltBody和MsgHTML。

您应该先将所有地址添加到BCC字段中,然后再发送。

所以请尝试...

// rest of code first
$mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
$mail->MsgHTML($body);
$mail->AddAddress("you@example.com")

$ids = mysql_query($select, $connection) or die(mysql_error());
while ($row = mysql_fetch_row($ids)) {
  $mail->AddBCC($row[0]);
}

$mail->Send();//Sends the email

Marc B的代码比我的原始代码更好 - 我描述得没错,但我的代码并没有反映出BCC建议。你应该遵循他添加一个“to”收件人(通常是自己,使用AddAddress),然后使用AddBCC为列表成员的电子邮件的示例。我已经编辑了我的代码以反映这一点。谢谢Marc! - JoLoCo
不仅你不需要每次设置MsgHTML,如果插入的文本在每封邮件中都不同,它还可能产生负面影响。 - Circum

2

使用BCC(秘密抄送)隐藏收件人列表。与垃圾邮件问题相关,这取决于收件人的电子邮件提供商将什么视为垃圾邮件,而不是垃圾邮件,还有许多其他因素。


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