PHP 8+下HTML邮件显示为文本格式的正确实现方式咨询
PHP 8+ 下HTML邮件显示为文本的修复方案
原代码在PHP8+中邮件显示为纯文本的核心原因是邮件头换行符不规范:PHP8对邮件头的格式校验变得更严格,要求必须符合RFC标准用\r\n作为头字段分隔符,但原代码拼接MIME头时混用了\n,导致邮件客户端无法正确解析MIME结构,只能按纯文本处理。另外原代码使用multipart/mixed(用于带附件的邮件)却无实际附件,属于不合理的MIME类型选择。
以下是两种适配PHP8+的正确实现方式:
方案一:保留Multipart结构(支持纯文本+HTML双版本,兼容性更好)
适用于需要同时提供纯文本 fallback 的场景,符合邮件标准:
$to = "Test Mail <test@test.gmail>"; $from = "Test Mail <test@test.gmail>"; $cc = "Test Mail <test@test.gmail>"; $subject = "TEST email"; // 统一用\r\n作为邮件头换行符 $headers = "From: $from\r\nCc: $cc"; $htmlContent = ' <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="fi-FI"> <body> <h1>HEADER OF THE EMAIL</h1> </body> </html> '; // 生成唯一MIME边界符 $semi_rand = md5(time()); $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; // 拼接MIME相关头,全部使用\r\n换行 $headers .= "\r\nMIME-Version: 1.0\r\nContent-Type: multipart/alternative;\r\n boundary=\"{$mime_boundary}\""; // 构建Multipart邮件内容,换行统一用\r\n $message = "This is a multi-part message in MIME format.\r\n\r\n"; $message .= "--{$mime_boundary}\r\n"; // 添加纯文本fallback(避免不支持HTML的客户端显示空白) $message .= "Content-Type: text/plain; charset=UTF-8\r\n"; $message .= "Content-Transfer-Encoding: 7bit\r\n\r\n"; $message .= "HEADER OF THE EMAIL(纯文本版本)\r\n\r\n"; // 添加HTML内容部分 $message .= "--{$mime_boundary}\r\n"; $message .= "Content-Type: text/html; charset=UTF-8\r\n"; $message .= "Content-Transfer-Encoding: 7bit\r\n\r\n"; $message .= $htmlContent . "\r\n\r\n"; // 关闭MIME边界 $message .= "--{$mime_boundary}--\r\n"; // 发送邮件(调试阶段去掉@,方便查看错误;上线后可按需加回) $ok = mail($to, $subject, $message, $headers);
关键修改点:
- 所有邮件头和内容的换行统一使用
\r\n,符合RFC邮件标准,适配PHP8+的严格校验 - 将
multipart/mixed改为multipart/alternative,这是同时提供纯文本和HTML版本的标准MIME类型 - 添加纯文本fallback,提升邮件在老旧客户端的兼容性
方案二:简化版(直接发送HTML邮件,无附件时推荐)
如果不需要纯文本版本,可直接设置HTML内容的邮件头,代码更简洁:
$to = "Test Mail <test@test.gmail>"; $from = "Test Mail <test@test.gmail>"; $cc = "Test Mail <test@test.gmail>"; $subject = "TEST email"; // 构建HTML邮件头,全部用\r\n换行 $headers = "From: $from\r\n"; $headers .= "Cc: $cc\r\n"; $headers .= "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: text/html; charset=UTF-8\r\n"; $headers .= "Content-Transfer-Encoding: 7bit"; $htmlContent = ' <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="fi-FI"> <body> <h1>HEADER OF THE EMAIL</h1> </body> </html> '; // 发送邮件 $ok = mail($to, $subject, $htmlContent, $headers);
内容的提问来源于stack exchange,提问作者NorthFred
相关产品推荐
相关产品推荐

