
使用 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免费学习笔记(深入)”;