You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP mail()函数发件异常求助:特定环境下邮件显示破损

问题分析与修复方案

核心问题确认

你推测的方向是对的:X-PHP-Originating-Script头部是触发问题的关键因素,但本质是邮件头的结构被破坏了。

ESET插入X-EsetId头部后留下了空行,而PHP原生mail()函数会自动在你自定义的headers之后追加X-PHP-Originating-Script,这就把原本应该连续的MIME核心头(MIME-Version、Content-type)推到了空行之后。根据邮件协议RFC标准,空行是邮件头和正文的分隔符,客户端会把空行后的所有内容当成纯文本正文,所以HTML标签直接暴露出来,邮件显示破损。

Laravel不发送这个头部,所以MIME头始终保持连续,不会被客户端误解析。

修复步骤

1. 禁用PHP自动添加X-PHP-Originating-Script

这是最直接的解决方法,有两种实现方式:

  • 全局配置:修改php.ini文件,设置mail.add_x_header = Off,修改后重启PHP服务生效。
  • 脚本临时配置:在调用mail()函数之前添加一行代码,仅对当前脚本生效:
    ini_set('mail.add_x_header', 'Off');
    

2. 修正邮件头的换行格式

邮件协议要求头部换行必须使用\r\n(CRLF),你当前脚本用的是\n(LF),这会增加解析异常的概率,修改headers的换行符:

$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= 'From: <email.address@example.com>' . "\r\n";

3. 可选:使用MIME多部分结构(支持纯文本备选)

如果你需要同时发送HTML和纯文本版本(对应你定义的$emailAltBody),手动构造多部分MIME结构可以提升邮件的兼容性,即使头信息出现小问题,客户端也能正确解析:

$subject = mb_encode_mimeheader('Subject text');
$emailAltBody = "..."; // 你的纯文本内容
$boundary = md5(time()); // 生成唯一的MIME边界

// 构造邮件头
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-Type: multipart/alternative; boundary=\"$boundary\"" . "\r\n";
$headers .= 'From: <email.address@example.com>' . "\r\n";

// 构造邮件内容
$emailContent = "--$boundary\r\n";
$emailContent .= "Content-Type: text/plain; charset=UTF-8\r\n\r\n";
$emailContent .= $emailAltBody . "\r\n";
$emailContent .= "--$boundary\r\n";
$emailContent .= "Content-Type: text/html; charset=UTF-8\r\n\r\n";
$emailContent .= '<!DOCTYPE html>
<html lang="cs">
    ...
</html>' . "\r\n";
$emailContent .= "--$boundary--";

// 发送邮件
$result = mail("email.address@example.com", $subject, $emailContent, $headers);

内容的提问来源于stack exchange,提问作者Filip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 02:07:10