PHP 8.1 邮件正文出现 --PHP-alt-... 前缀的成因与修复方案

千强姑娘_4643

千强姑娘_4643

2026-09-14

821人浏览

原创

PHP 8.1 邮件正文出现 --PHP-alt-... 前缀的成因与修复方案

PHP 8.1 升级后,使用 mail() 发送 multipart/alternative 邮件时,正文头部意外显示边界标记(如 --PHP-alt-xxx),根本原因是换行符不规范(误用 \n\n 而非 \r\n),导致 MIME 结构解析异常,被收件客户端误作明文内容渲染。

php 8.1 升级后,使用 `mail()` 发送 multipart/alternative 邮件时,正文头部意外显示边界标记(如 `--php-alt-xxx`),根本原因是换行符不规范(误用 `\n\n` 而非 `\r\n`),导致 mime 结构解析异常,被收件客户端误作明文内容渲染。

在 PHP 8.1(尤其是 8.1.31 及后续维护版本)中,mail() 函数对邮件协议规范的校验更加严格。RFC 2822 明确规定:邮件头与正文之间、各 MIME 部分之间必须使用 \r\n(CRLF)作为行终止符,而不能仅用 \n(LF)。你提供的代码中,虽然 $headers$body 数组拼接时使用了 implode("\r\n", ...),但关键隐患隐藏在 MIME 部分之间的空行构造逻辑中:

// ❌ 错误示例:此处使用了 "\n"(LF),违反 RFC 标准
$body[] = ""; // ← 这个空行实际是 "\n",不是 "\r\n"

implode("\r\n", $body) 执行时,数组元素间插入 \r\n,但每个 $body[] = "" 本身仅贡献一个 \n —— 最终生成类似 --boundary\r\nContent-Type: ...\r\nContent-Transfer-Encoding: 8bit\r\n\nYour message 的结构。中间的 \n\n(即两个 LF)被部分 MTA 或客户端识别为“头尾分隔符”,但因不符合 \r\n\r\n 规范,导致后续内容(包括边界标记)未被正确解析为 MIME 控制指令,而是原样落入邮件正文。

✅ 正确做法是:所有空行必须显式写为 "\r\n",而非 ""。同时确保整个 MIME 结构严格遵循 RFC 标准:

<?php $random_hash = md5(uniqid(time(), true));
$from = 'From: "Site Name" <webmaster@example.com>';
$fromemail = 'webmaster@example.com';
$email = 'user@example.com';
$subject = 'HTML 邮件测试';
$message = '这是纯文本内容';
$html_message = '<p>这是<strong>HTML</strong>内容</p><div class="aritcle_card flexRow artxards">
											<div class="artcardd flexRow">
												<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill2138" title="PHP"><img
														src="https://img.php.cn/upload/skill/000/000/081/178884013267959.jpg" alt="PHP" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
												<div class="aritcle_card_info flexColumn">
													<a rel="nofollow" href="/xiazai/skill2138" title="PHP" class="overflowclass">PHP</a>
													<p class="overflowclass">编写健壮的PHP代码,规避类型转换陷阱、数组怪癖及常见安全漏洞。</p>
												</div>
												<a rel="nofollow" href="/xiazai/skill2138" title="PHP" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
												</a>
											</div>
										</div>';

// ✅ 正确构造 headers(全部使用 \r\n 换行)
$headers = [
    $from,
    "Reply-To: $fromemail",
    "Content-Type: multipart/alternative; boundary=\"PHP-alt-$random_hash\"",
    "MIME-Version: 1.0",
    "X-PHP-Script: " . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']
];

// ✅ 正确构造 body:空行必须为 "\r\n",不可为 ""
$body = [];

// Plain text part
$body[] = "--PHP-alt-$random_hash";
$body[] = "Content-Type: text/plain; charset=\"utf-8\"";
$body[] = "Content-Transfer-Encoding: 8bit";
$body[] = "\r\n"; // ← 关键!显式使用 \r\n 表示空行
$body[] = $message;

// HTML part
$body[] = "--PHP-alt-$random_hash";
$body[] = "Content-Type: text/html; charset=\"utf-8\"";
$body[] = "Content-Transfer-Encoding: 8bit";
$body[] = "\r\n"; // ← 同样必须是 \r\n
$body[] = "<meta http-equiv='\"Content-Type\"' content='\"text/html;' charset='utf-8\"'><title>$subject</title>$html_message";

// Final boundary
$body[] = "--PHP-alt-$random_hash--";

// ✅ 安全拼接(注意:结尾不能有多余 \r\n)
$full_body = implode("\r\n", $body);
$full_headers = implode("\r\n", $headers);

// 发送并检查结果
if (mail($email, $subject, $full_body, $full_headers)) {
    echo "✅ 邮件发送成功(MIME 结构已合规)";
} else {
    error_log("❌ mail() 返回 false,请检查服务器 MTA 状态及日志");
}
?>

⚠️ 重要注意事项

  • 不要依赖 PHP_EOLPHP_EOL 在 Linux 是 \n,Windows 是 \r\n,而邮件协议要求统一为 \r\n,必须硬编码;
  • 避免多余空白$headers$body 数组末尾不应有空字符串或空格,否则可能引入非法 \r\n(带空格);
  • 字符编码需显式声明Content-Typecharset="utf-8" 必须存在,中文内容建议对 $message$html_message 使用 mb_encode_mimeheader() 处理主题,或对正文启用 mb_internal_encoding('UTF-8')
  • 生产环境强烈建议迁移到 SMTP 库mail() 仅适合开发测试;真实项目请使用 PHPMailerSymfony Mailer,它们自动处理 MIME、编码、认证与错误反馈,规避底层协议陷阱。

综上,--PHP-alt-... 出现在正文,不是 PHP 8.1 的 Bug,而是 MIME 构造不合规的必然表现。修正换行符、严守 RFC 2822,即可彻底解决。

php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

8924

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

5441

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

1995

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

3368

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

4034

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

3151

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

4477

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

3482

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

11542

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
墨刀帮助中心
墨刀帮助中心

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

Apache Subversion 官方手册
Apache Subversion 官方手册

共0课时 | 0人学习