PHP Mailer关闭调试时重复发3-4封邮件 开启调试仅发1次问题求助
问题原因与解决方案
核心问题排查方向
先通过添加调用日志快速定位问题发生的层面:
在SendEmail()函数第一行添加以下代码,记录函数的实际调用次数:
file_put_contents(__DIR__.'/mail_send_log.txt', date('[Y-m-d H:i:s]') . " 触发邮件发送\n", FILE_APPEND);
单次访问业务页面后查看日志行数,分两种情况处理:
情况1:日志记录多条(PHP层面被多次调用)
- 检查本地服务的重写规则(比如Apache的.htaccess、Nginx的try_files配置),确认是否将favicon.ico、静态资源请求、OPTIONS预检请求错误路由到了业务入口脚本
- 检查业务代码中是否存在
header('Location: xxx')后未加exit/die的情况,导致跳转前代码先执行一次,跳转后又执行一次 - 确认是否开启了浏览器的预渲染/预加载功能,部分浏览器会提前请求鼠标悬停的链接,导致逻辑被提前触发
情况2:日志仅记录1条(PHPMailer内部重复发送)
你的代码存在3处不合理配置,共同触发了PHPMailer的SMTP自动重试机制,开启调试时会输出交互日志打断重试流程,所以仅发送1次:
isSMTP()调用位置错误:必须放在所有SMTP相关配置的最前面,你当前先配置SMTP参数再开启SMTP模式,会导致部分配置未生效,引发连接异常重试- 重复配置
SMTPSecure,且手动设置了带换行符的ContentType,导致邮件头格式错误,SMTP服务器交互异常触发重试 - PHPMailer 6.x默认SMTP重试次数为3次,关闭调试模式时出错会自动重试,你看到的3-4封就是默认重试的结果
修复后的代码
修改SendEmail()函数内的配置顺序,关闭自动重试,删除错误的头配置:
function SendEmail(){ $mail = new PHPMailer(true); $mail->SMTP_RETRY_COUNT = 1; // 关闭自动重试 try { // 先开启SMTP模式再配置参数 $mail->isSMTP(); //Server settings $mail->SMTPDebug = SMTP::DEBUG_OFF; $mail->SMTPAuth = true; $mail->Host = '*****'; $mail->Username = '*****'; $mail->Password = '*****'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; $mail->Port = 465; $mail->SMTPAutoTLS = false; $mail->SMTPOptions = array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ) ); $mail->ClearAllRecipients(); $mail->clearAttachments(); //Recipients $mail->setFrom('*****', '******'); $mail->addAddress('*******', '*****'); $mail->addReplyTo('******', '******'); //Attachments $mail->addAttachment(ABSPATH.'upload/dog.jpg', 'new.jpg'); //Content $mail->isHTML(true); $mail->Subject = md5(rand()); $mail->Body = 'This is the HTML message body <b>in bold!</b>'. md5(rand()); $mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; $mail->send(); echo 'Message has been sent'; } catch (Exception $e) { echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}"; } }
内容的提问来源于stack exchange,提问作者Ahmed Essam
相关产品推荐
相关产品推荐

