PHPMailer多收件人CC异常:抄送收件箱收到75份重复邮件问题
批量邮件抄送重复接收问题修复
我数据库内有75个用户邮箱,通过表单传参到sendmail.php执行批量发送。设置抄送地址后,我的收件箱收到了75份抄送邮件,添加$mail->clearAddresses();后问题仍未解决。需求是给每个用户单独发送一封邮件,每封邮件同时抄送指定收件人。
当前问题代码
<?php /** * Send email to a list of recipients with phpMailer. */ //============================================================ database connection // code goes here // ============================================================= end db connection use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; require 'PHPMailer/src/Exception.php'; require 'PHPMailer/src/SMTP.php'; require 'PHPMailer/src/PHPMailer.php'; //=================================================================== if(isset($_POST['send'])) { $administrator= $_POST['administrator'] ; $sender= $_POST['sender']; $from= $_POST['sender']; $from_email= $_POST['from_email'] ; $replyto= $_POST['from_email'] ; $subject= $_POST['subject'] ; $message = $_POST['message']; $cc= $_POST['cc'] ; $sig_block= $_POST['sig_block'] ; $fileName= $_POST['fileName'] ; $location = "PHPMailer/attachments/"; $subject = "$subject"; $message = "$message<p>$sig_block"; //=============================== $mail = new PHPMailer(true); try { //Server settings $mail->isSMTP(); $mail->SMTPAuth = true; $mail->Host = 'smtp.xxx.com'; $mail->Username = 'email address'; $mail->Password = 'password'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->SMTPKeepAlive = true; $mail->Port = 587; //Attachment if(strlen($fileName) >=4) { $mail->addAttachment($location.$fileName); } //Content $mail->isHTML(true); $mail->Subject = $subject; $mail->Body = $message; //Recipients $mail->setFrom('email@domain', 'Webmaster'); if(strlen($cc) >=4) { $mail->addCC($cc); } $mail->addReplyTo($replyto, $sender); //Reply to sender email $mail->addAddress($from_email, $sender); //copy sent to sender //---------------------------------------------------------------------- // Access database $sql= $conn->prepare(" SELECT fname, lname, email FROM members WHERE year_pd = '$year' ORDER BY lname "); $sql->execute(); while ($row = $sql->fetch()) { $fname= $row['fname']; $lname= $row['lname']; $to= $row['email']; $mail->clearAddresses() ; } // close while } // close try catch (Exception $e) { echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo; } ?>
问题根源
- 未清理抄送列表:
clearAddresses()仅清理收件人(To)地址,不会清除抄送(CC)地址,循环外添加的CC会被保留到每一封邮件中。 - 核心逻辑缺失:循环内仅清理收件人,未添加数据库用户作为新收件人,也没有调用
send()发送邮件。 - 收件人配置错误:给自己的邮箱添加了固定收件人,且放在循环外,导致该地址被加入每封邮件的收件列表。
修正后的代码
<?php /** * Send email to a list of recipients with phpMailer. */ //============================================================ database connection // code goes here // ============================================================= end db connection use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; require 'PHPMailer/src/Exception.php'; require 'PHPMailer/src/SMTP.php'; require 'PHPMailer/src/PHPMailer.php'; //=================================================================== if(isset($_POST['send'])) { $administrator = $_POST['administrator']; $sender = $_POST['sender']; $from_email = $_POST['from_email']; $replyto = $_POST['from_email']; $subject = $_POST['subject']; $message = $_POST['message']; $cc = $_POST['cc']; $sig_block = $_POST['sig_block']; $fileName = $_POST['fileName']; $location = "PHPMailer/attachments/"; $message .= "<p>" . $sig_block; $mail = new PHPMailer(true); try { // 服务器配置(仅需设置一次) $mail->isSMTP(); $mail->SMTPAuth = true; $mail->Host = 'smtp.xxx.com'; $mail->Username = 'email address'; $mail->Password = 'password'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->SMTPKeepAlive = true; $mail->Port = 587; // 邮件内容配置(仅需设置一次) $mail->isHTML(true); $mail->Subject = $subject; $mail->Body = $message; $mail->setFrom('email@domain', 'Webmaster'); $mail->addReplyTo($replyto, $sender); // 添加附件(仅需设置一次) if(strlen($fileName) >=4) { $mail->addAttachment($location . $fileName); } // 数据库查询(使用参数绑定避免SQL注入) $sql = $conn->prepare(" SELECT fname, lname, email FROM members WHERE year_pd = ? ORDER BY lname "); $sql->execute([$year]); // 循环发送邮件 while ($row = $sql->fetch()) { $toName = $row['fname'] . ' ' . $row['lname']; $toEmail = $row['email']; // 清理上一次的收件人和抄送列表 $mail->clearAddresses(); $mail->clearCCs(); // 添加当前用户为收件人 $mail->addAddress($toEmail, $toName); // 添加抄送地址(如果存在) if(strlen($cc) >=4) { $mail->addCC($cc); } // 给自己发送副本 $mail->addAddress($from_email, $sender); // 发送邮件 $mail->send(); } echo "所有邮件发送完成!"; } catch (Exception $e) { echo '邮件发送失败:', $mail->ErrorInfo; } finally { // 关闭SMTP连接 $mail->smtpClose(); } } ?>
关键修改说明
- 清理抄送列表:每次循环调用
clearCCs()确保抄送地址不会重复添加。 - 循环内完成完整发送流程:在循环中添加收件人、抄送,调用
send()发送邮件,保证每封邮件独立。 - SQL注入防护:将原代码中的字符串拼接改为参数绑定,提升安全性。
- 优化配置逻辑:将无需重复设置的服务器、内容、附件配置移到循环外,提升发送效率。
- 关闭SMTP连接:批量发送完成后调用
smtpClose()释放连接资源。
内容的提问来源于stack exchange,提问作者Phil R
相关产品推荐
相关产品推荐

