必须捕获phpmailer\exception而非通用exception,并在$mail->send()返回false或抛异常时均调用geterrorinfo()获取结构化错误信息,禁用含敏感信息的errorinfo字符串。

捕获 PHPMailer\Exception 而不是通用 Exception
直接 catch (Exception $e) 会漏掉 PHPMailer 的关键子类错误,比如 SMTPAuthenticationError 或 SMTPConnectError。这些子类携带了协议层的真实失败原因,而父类 Exception 只能告诉你“出错了”,没法区分是密码错、端口拒连还是 TLS 协议不匹配。
必须显式捕获 PHPMailer\PHPMailer\Exception:
use PHPMailer\PHPMailer\Exception;
try {
$mail->send();
} catch (Exception $e) {
// 这里才能拿到结构化错误
$errorInfo = $mail->getErrorInfo();
Log::error('Mail send failed', ['error' => $errorInfo]);
}
常见错误现象:$e->getMessage() 显示 “Message could not be sent”,但没线索;实际要的是 $mail->getErrorInfo() 返回的数组。
调用 $mail->getErrorInfo() 拿结构化错误,别用 $mail->ErrorInfo
$mail->ErrorInfo 是字符串,含完整 SMTP 响应(比如 535 Error: authentication failed),可能泄露账号、服务器 IP、时间戳等敏感信息,不能直接记录或输出。
$mail->getErrorInfo() 返回关联数组,字段明确、可控:
-
error:简短错误类型(如smtp、from) -
smtp_code和smtp_code_ex:标准 SMTP 状态码(如535) -
detail:可安全记录的描述(如Authentication failed)
示例:
if (!$mail->send()) {
$info = $mail->getErrorInfo();
// 安全记录
Log::warning('Email failed', [
'type' => $info['error'],
'code' => $info['smtp_code'] ?? null,
'detail' => $info['detail'] ?? ''
]);
}
检查 $mail->send() === false 才触发错误收集
$mail->send() 不抛异常时也会返回 false,比如发信人地址格式错误、附件路径不存在、SMTP 连接成功但认证失败后静默返回 false。只靠 try/catch 会漏掉这类情况。
必须同时检查返回值:
- 返回
true→ 成功 - 返回
false→ 失败,立刻调用$mail->getErrorInfo() - 抛出
PHPMailer\PHPMailer\Exception→ 协议层严重异常(如 socket 连接中断)
所以健壮写法是:
try {
$sent = $mail->send();
if (!$sent) {
$info = $mail->getErrorInfo();
// 记录并处理
}
} catch (Exception $e) {
$info = $mail->getErrorInfo();
// 同样记录
}
日志中避免拼接 $mail->ErrorInfo 字符串
很多调试习惯是 Log::error($mail->ErrorInfo),这很危险。它可能包含:
- 完整 SMTP 响应中的认证失败提示(暴露用户名)
- 服务器内部域名或 IP(如
mail.qq.com[123.123.123.123]) - 时间戳和会话 ID(可用于追踪攻击链)
生产环境日志必须过滤掉原始 ErrorInfo。真正需要的只是 getErrorInfo() 中的 detail 和 smtp_code —— 它们足够定位问题,又不带敏感上下文。
复杂点在于:不同邮箱服务商对同一错误返回的 detail 颗粒度不一,QQ 邮箱可能只回 Authentication failed,而 Gmail 会返回 535-5.7.8 Username and Password not accepted。得结合 smtp_code 做判断,不能只看文字。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











