
PHP 使用 text/html 邮件头后,\n 换行符失效,需改用 标签或切换为纯文本格式;本文详解原理、修复方案及最佳实践。
php 使用 `text/html` 邮件头后,`\n` 换行符失效,需改用 `
` 标签或切换为纯文本格式;本文详解原理、修复方案及最佳实践。
在 PHP 中通过 mail() 发送邮件时,若在 $headers 中声明了 'Content-type: text/html; charset=utf-8',就意味着你明确告诉邮件客户端:这是一封 HTML 格式的邮件。此时,邮件正文将被当作 HTML 文档解析——而 HTML 规范中,普通换行符 \n 或 \r\n 不会渲染为可视换行,它们仅作为空白字符被忽略(类似 HTML 中的多个空格只显示为一个)。真正起作用的换行标记是 HTML 标签
。
因此,原始代码中使用 \n 拼接的 $msg:
$msg = "Antwort an: $useremail\n". "Name: $username $lastname \n". "Telefonnummer: $fon \n". "Nachricht: $usermsg";
在 text/html 模式下会全部显示为一行(无换行),造成可读性严重下降。
✅ 正确做法有以下两种,推荐根据实际需求选择:
立即学习“PHP免费学习笔记(深入)”;
方案一:保持 HTML 格式,改用
标签(快速修复)
只需将所有 \n 替换为
,并确保内容已做 HTML 安全处理(防止 XSS):
// ✅ 推荐:HTML 模式下使用 <br> + htmlspecialchars() 防注入
$msg = "Antwort an: " . htmlspecialchars($useremail) . "<br>" .
"Name: " . htmlspecialchars($username) . " " . htmlspecialchars($lastname) . "<br>" .
"Telefonnummer: " . htmlspecialchars($fon) . "<br>" .
"Nachricht: " . nl2br(htmlspecialchars($usermsg)); // nl2br 将用户输入中的 \n 转为 <br>⚠️ 注意:htmlspecialchars() 必须对所有用户输入(如 $username, $usermsg)进行转义,否则恶意 HTML 或脚本可能被直接执行。
方案二:改用纯文本格式(更安全、更简洁)
若无需加粗、链接等富文本效果,强烈推荐退回 text/plain 模式——它天然支持 \n 换行,且无 XSS 风险:
$headers = 'Content-Type: text/plain; charset=utf-8' . "\r\n"
. 'From: ' . $myemail . "\r\n";
$msg = "Antwort an: $useremail\n" .
"Name: $username $lastname\n" .
"Telefonnummer: $fon\n" .
"Nachricht:\n$usermsg"; // 用户输入中的 \n 可保留(但建议用 wordwrap() 控制行长)? 小技巧:对长文本(如 $usermsg)可配合 wordwrap($msg, 70, "\n", true) 避免超长行被某些邮件客户端截断。
⚠️ 关键注意事项总结
- ❌ 不要混用:不要在 text/html 头中发送纯 \n,也不要 text/plain 中写
; - ✅ 字符编码一致:charset=utf-8 在 text/plain 和 text/html 中均有效,确保中文不乱码;
- ? 安全第一:HTML 模式下务必转义所有动态内容;text/plain 模式虽免于 XSS,但仍需过滤敏感控制字符(如 \0);
- ? 兼容性提示:部分老旧邮件客户端对 UTF-8 支持较弱,可补充 Content-Transfer-Encoding: quoted-printable 头增强兼容性(非必需)。
选择方案二(text/plain)通常是更稳健、更易维护的选择;仅当业务明确需要邮件内嵌链接、样式或表格时,才启用 HTML 模式,并严格遵循输出转义规范。











