
邮件客户端(如 Gmail)会自动折行过长的 HTML 行,将换行符转换为 %20(空格编码),导致 URL 被破坏;解决方案是控制每行长度或使用 base64 编码邮件正文。
邮件客户端(如 gmail)会自动折行过长的 html 行,将换行符转换为 `%20`(空格编码),导致 url 被破坏;解决方案是控制每行长度或使用 base64 编码邮件正文。
在 PHP 中通过 mail() 发送 HTML 邮件时,若 <a href="..."> 链接中的 URL 出现意外的 %20(如 documen%20tControl),并非代码中存在空格,而是邮件传输过程中被客户端或中间 MTA(邮件传输代理)强制折行所致。RFC 2822 规定:纯文本邮件行长度不应超过 998 字符,而许多邮件服务(尤其是 Gmail)会对超长 HTML 行插入软换行(soft line break),并用空格(URL 编码为 %20)连接,从而破坏 URL 结构。
✅ 根本原因与验证方式
- 你原始代码中 "<style>...</style><div>..." 是单行超长字符串(远超 1000 字符),PHP 拼接后未换行,但邮件发送时被自动截断。
- %20 出现在 documentControl 中间(documen%20tControl),正是因折行发生在 document 和 Control 之间,空格被 URL 编码。
✅ 推荐解决方案(二选一)
方案一:手动换行,控制行宽(简单直接)
将 $email_body 字符串拆分为多行(推荐每行 ≤ 76 字符),避免自动折行干扰:
$email_body = "<style type='text/css'>\n" .
"BODY {FONT-FAMILY: arial,helvetica,sans-serif,verdana; FONT-SIZE: 14px;}\n" .
".heading {FONT-FAMILY: arial,helvetica,sans-serif,verdana; FONT-SIZE: 16px; FONT-WEIGHT: bold;}\n" .
"th {text-align: left; padding-right: 10px; padding-bottom:5px}\n" .
"td {padding-bottom:5px}\n" .
"</style>\n" .
"<div>Hello</div><br />\n" .
"<div>$body_one</div><br />\n" .
"<table>\n" .
"<tr><th>File:</th><td><a href='http://rfp.wabtec.com/docs/documentSystem/docs/$file'>$name</a></td></tr>\n" .
"<tr><th>Type:</th><td>$type</td></tr>\n" .
"<tr><th>Description:</th><td>$description</td></tr>\n" .
"</table><br />\n" .
"<div>$body_two</div><br />\n" .
"<div class='heading'>$heading</div><br />";✅ 关键点:
- 使用 \n 显式换行,确保每行 HTML 逻辑清晰且长度可控;
- mail() 函数会保留这些换行符,避免被邮件服务商二次处理;
- 不影响渲染效果(HTML 忽略普通换行)。
方案二:启用 Base64 编码(更健壮)
修改邮件头,启用 Content-Transfer-Encoding: base64,彻底规避折行风险:
// 替换原有 $email_headers
$email_headers = "MIME-Version: 1.0\r\n" .
"Content-Type: text/html; charset=utf-8\r\n" .
"Content-Transfer-Encoding: base64\r\n" .
"From: RFPC Document System <[email protected]>\r\n" .
"Reply-To: RFPC Document System <[email protected]>\r\n";
// Base64 编码正文(注意:必须 UTF-8 编码)
$email_body_encoded = base64_encode(
mb_convert_encoding($email_body, 'UTF-8', 'auto')
);
$email_send = @mail($email_to, $email_subject, $email_body_encoded, $email_headers);✅ 优势:
- Base64 编码后的数据每行严格限制为 76 字符(符合 RFC),无歧义;
- 完全规避 URL 被篡改风险;
- 兼容所有主流邮箱(Gmail、Outlook、Apple Mail 等)。
⚠️ 注意事项
- 勿依赖 @mail() 的默认行为:PHP mail() 不处理 MIME 编码,需手动设置头信息;
- URL 中禁止含中文/特殊字符:即使修复折行,仍建议对动态参数(如 $file)做 rawurlencode() 处理;
- 测试真实环境:本地 mail() 可能不触发折行,务必在 Gmail 等实际收件箱中验证链接;
- 升级建议:生产环境推荐使用 PHPMailer 或 Symfony Mime,其内置 MIME 处理与自动编码,大幅降低此类问题发生概率。
通过控制行宽或启用 Base64 编码,即可彻底解决邮件链接被注入 %20 的问题,确保用户点击直达目标页面,提升审批流程可靠性。

















