php_eol会破坏smtp邮件头,因其在linux/macos返回\n(lf)而非协议强制要求的\r\n(crlf),导致头字段截断、解析失败;必须显式使用\r\n拼接所有头行,末行也需保留,或改用phpmailer等自动合规的库。

PHP系统常量PHP_EOL在邮件头中直接使用,会导致换行符不兼容SMTP协议,进而引发邮件头截断、收件人无法识别、甚至整封邮件被拒收。这不是代码逻辑错误,而是协议层的底层规范冲突。
为什么PHP_EOL会破坏邮件头
SMTP协议严格要求邮件头使用\r\n(CRLF)作为换行分隔符,而PHP_EOL在不同系统返回不同值:
– Linux/macOS 返回 \n(LF)
– Windows 返回 \r\n(CRLF)
一旦邮件头中混入\n,SMTP服务器会将其视为头字段结束,后续内容(如To:、Subject:)被当作邮件正文处理,造成解析失败。
邮件头中必须手动写死\r\n
所有邮件头字段拼接时,禁止用PHP_EOL,一律显式使用"\r\n":
-
错误写法:
$headers = "From: me@example.com" . PHP_EOL . "Reply-To: me@example.com"; -
正确写法:
$headers = "From: me@example.com\r\nReply-To: me@example.com\r\n"; - 每行结尾都要有
\r\n,最后一行也必须保留,否则可能被某些MTA截断 - 避免末尾多出空行或
\r\n\r\n——那会提前结束邮件头,把后面内容全当成正文
改用PHPMailer等库可自动规避该问题
PHPMailer内部统一使用\r\n构造邮件头,并做RFC 2822合规性校验。启用调试模式还能暴露头字段拼接过程:
- 设置
$mail->SMTPDebug = 2;,查看实际发出的原始SMTP对话 - 确认
MAIL FROM和RCPT TO指令前,DATA段头是否完整、无LF混入 - 若仍出现截断,检查是否手动调用了
$mail->addCustomHeader()并误用了PHP_EOL
验证与快速检测方法
不依赖收件箱反馈,直接抓取原始协议流判断:
- 用
telnet smtp.gmail.com 587手动模拟SMTP会话,观察DATA后首段是否格式正常 - 在PHPMailer中设置
$mail->Debugoutput = 'error_log';,查日志里CLIENT -> SERVER部分的From:、To:是否连续出现在头区 - 对自建MTA(如Postfix),检查
/var/log/mail.log中是否有invalid header或truncated header提示
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











