
使用 phpmailer 循环发送个性化邮件时,若未在每次发送后清除收件人地址,会导致后续邮件不断累积前序收件人,最终所有收件人均收到全部邮件。解决关键是调用 `clearaddresses()` 或 `clearallrecipients()` 重置收件人列表。
在 PHPMailer 中,addAddress()、addCC() 和 addBCC() 方法并不会自动覆盖已有收件人,而是累加到内部收件人列表中。因此,当在循环中重复调用 $mail->addAddress($mailAdres, $name) 而不清理时,第二次迭代会保留第一次的收件人,第三次又追加……最终所有邮件都发给了全部用户——这正是你遇到的“所有人收到所有人信息”的根本原因。
✅ 正确做法是在每次成功调用 $mail->send() 后,立即清除当前收件人配置:
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->addAddress($mailAdres, $name);
$mail->isHTML(true);
$mail->CharSet = 'UTF-8';
$mail->Subject = $odemeType;
$mail->Body = $mail_template;
$mail->AltBody = '';
try {
$mail->send();
// ✅ 关键:仅清除 To 收件人(适用于未使用 CC/BCC 的场景)
$mail->clearAddresses();
// 若你同时使用了 addCC() 或 addBCC(),请改用:
// $mail->clearAllRecipients();
} catch (Exception $e) {
error_log("邮件发送失败(ID: {$mailId}): " . $mail->ErrorInfo);
continue; // 跳过当前用户,继续下一轮
}
}⚠️ 注意事项:
- clearAddresses() 仅清空 To 字段;若代码中调用了 addCC() 或 addBCC(),务必改用 clearAllRecipients(),否则 CC/BCC 地址仍会残留;
- 每次发送前无需重新初始化 $mail 对象(如 new PHPMailer()),但必须清除收件人、重置主体内容(Body/Subject 等)——本例中已通过循环内赋值保证内容独立;
- 强烈建议将 send() 包裹在 try...catch 中,避免单个邮件失败导致整个循环中断;
- 如需提升性能与可靠性,可考虑使用批量 SMTP 连接复用(启用 SMTPKeepAlive = true)或改用队列异步发送,尤其在用户量较大时。
总结:PHPMailer 的收件人列表是持久累积的,“发送即清理”是循环发送的黄金法则。牢记 clearAddresses()(基础场景)或 clearAllRecipients()(含 CC/BCC 场景),即可确保每封邮件精准、独立地送达对应收件人。
立即学习“PHP免费学习笔记(深入)”;











