
使用 phpmailer 循环发送邮件时,若未及时清空收件人列表,会导致后续邮件不断累积地址,最终所有收件人收到全部人的信息。解决关键是在每次 send() 后调用 clearaddresses() 或 clearallrecipients()。
在 PHPMailer 中,addAddress()、addCC() 和 addBCC() 方法会持续累积收件人,而非覆盖。这意味着:即使你在每次循环中只添加一个收件人,PHPMailer 内部的收件人列表仍会保留上一轮已添加的所有地址——除非你主动清除。
例如,原始代码中:
foreach ($id as $mailId) {
// ... 获取用户数据
$mail->addAddress($mailAdres, $name);
// ... 设置内容
$mail->send(); // ❌ 缺少清理!
}第一次循环发送给 A@example.com;
第二次循环调用 addAddress() 后,收件人变为 A@example.com, B@example.com;
第三次则变成 A, B, C……以此类推,最终所有人收到全部邮件。
✅ 正确做法是在每次成功发送后立即清空收件人列表:
foreach ($id as $mailId) {
$connect->connect('account where id=:id', array('id' => $mailId), '', 0);
$users = $connect->connect->fetch(PDO::FETCH_ASSOC);
$name = $users['name'];
$mailAdres = $users['mail'];
$mail_template = $name;
$mail->isHTML(true);
$mail->CharSet = 'UTF-8';
$mail->Subject = $odemeType;
$mail->Body = $mail_template;
$mail->AltBody = '';
$mail->addAddress($mailAdres, $name);
// 若使用了 CC/BCC,请确保一并清除(见下文)
try {
$mail->send();
echo "Email sent to {$name} ({$mailAdres})\n";
} catch (Exception $e) {
echo "Failed to send to {$name}: {$mail->ErrorInfo}\n";
}
// ✅ 关键:重置收件人列表,为下一次发送做准备
$mail->clearAddresses(); // 仅清除 To 地址
// $mail->clearAllRecipients(); // 推荐:清除 To/CC/BCC 全部收件人
}⚠️ 注意事项:
立即学习“PHP免费学习笔记(深入)”;
- clearAddresses() 仅清除 To 字段,若代码中使用了 addCC() 或 addBCC(),必须改用 clearAllRecipients(),否则 CC/BCC 地址仍会累积;
- 建议在 try...catch 中调用 send(),避免因某封邮件失败导致整个流程中断;
- 若需提升性能(如大批量发送),可考虑使用 SMTP Keep-Alive(PHPMailer 默认启用)或队列系统,但切勿省略每次发送后的收件人清理;
- 模板内容(如 $mail_template)应确保每次循环独立生成,避免变量污染。
总结:PHPMailer 的地址管理是“追加式”而非“覆盖式”,循环发送的核心原则是——发完即清。加上 clearAllRecipients() 这一行,即可彻底杜绝“一人收全量邮件”的逻辑错误。











