PHP应用中HTML邮件渲染异常问题求助
PHP HTML邮件渲染异常修复方案
问题核心原因
原代码存在以下关键错误:
- HTML邮件类型判断逻辑错误
- 未对base64/quoted-printable编码的邮件内容解码
- 错误将邮件内容包裹在
<style>标签中导致代码暴露 - 未处理
cid:格式的图片资源路径
分步修复方案
1. 修复HTML邮件类型判断
IMAP协议中,type=0表示TEXT类型,HTML属于TEXT的子类型,修正判断逻辑:
$isHTML = false; if ($structure->type == 0) { // 处理多部分邮件 if (isset($structure->parts)) { foreach ($structure->parts as $index => $part) { if (strtoupper($part->subtype) == 'HTML') { $isHTML = true; break; } } } // 处理单部分HTML邮件 if (strtoupper($structure->subtype) == 'HTML') { $isHTML = true; } }
2. 添加邮件内容解码函数
处理常见的邮件编码格式:
function decodeEmailContent($content, $encoding) { switch(strtoupper($encoding)) { case 'BASE64': return base64_decode($content); case 'QUOTED-PRINTABLE': return quoted_printable_decode($content); default: return $content; } }
3. 正确获取并解码HTML内容
适配单/多部分邮件结构,解码后获取真实内容:
$messageBody = ''; if ($isHTML) { if ($structure->type == 0 && isset($structure->parts)) { foreach ($structure->parts as $index => $part) { if (strtoupper($part->subtype) == 'HTML') { $messageBody = imap_fetchbody($mailbox, $i, $index+1); // IMAP部分索引从1开始 $messageBody = decodeEmailContent($messageBody, $part->encoding); break; } } } else { $messageBody = imap_fetchbody($mailbox, $i, 1); $messageBody = decodeEmailContent($messageBody, $structure->encoding); } } else { $messageBody = imap_fetchbody($mailbox, $i, 1); $messageBody = decodeEmailContent($messageBody, $structure->encoding); }
4. 修复HTML渲染与图片路径问题
移除错误的<style>包裹,处理cid:图片(需额外保存附件到服务器生成可访问URL):
if ($isHTML) { // 替换cid图片为可访问路径(示例:需实现附件匹配逻辑) $messageBody = preg_replace('/cid:([a-zA-Z0-9\-_]+)/', function($matches) use ($mailbox, $i) { // 实际项目中需遍历邮件附件,根据cid匹配并生成临时访问URL return $matches[0]; }, $messageBody); // 直接渲染HTML内容,若用Mustache需用{{{messageBody}}}(不转义HTML) echo $messageBody; } else { echo nl2br(htmlspecialchars($messageBody)); }
完整修正代码
<?php use Mustache_Engine; use Mustache_Loader_FilesystemLoader; require_once '/home/dashboard/vendor/autoload.php'; function decodeEmailContent($content, $encoding) { switch(strtoupper($encoding)) { case 'BASE64': return base64_decode($content); case 'QUOTED-PRINTABLE': return quoted_printable_decode($content); default: return $content; } } $server = '{test severy:993/imap/ssl}INBOX'; $username = 'XXX@gmail'; $password = 'password'; $mailbox = imap_open($server, $username, $password) or die('Cannot connect to the server: ' . imap_last_error()); $totalMessages = imap_num_msg($mailbox); for ($i = 1; $i <= $totalMessages; $i++) { $header = imap_headerinfo($mailbox, $i); $structure = imap_fetchstructure($mailbox, $i); $isHTML = false; $messageBody = ''; // 判断HTML邮件类型 if ($structure->type == 0) { if (isset($structure->parts)) { foreach ($structure->parts as $index => $part) { if (strtoupper($part->subtype) == 'HTML') { $isHTML = true; $messageBody = imap_fetchbody($mailbox, $i, $index+1); $messageBody = decodeEmailContent($messageBody, $part->encoding); break; } } } if (strtoupper($structure->subtype) == 'HTML' && !$isHTML) { $isHTML = true; $messageBody = imap_fetchbody($mailbox, $i, 1); $messageBody = decodeEmailContent($messageBody, $structure->encoding); } } // 未找到HTML则获取纯文本 if (!$isHTML) { $messageBody = imap_fetchbody($mailbox, $i, 1); $messageBody = decodeEmailContent($messageBody, $structure->encoding); } echo '<strong>From:</strong> ' . $header->fromaddress . '<br>'; echo '<strong>Subject:</strong> ' . htmlspecialchars($header->subject) . '<br>'; echo '<strong>Date:</strong> ' . date('Y-m-d H:i:s', strtotime($header->date)) . '<br>'; echo '<strong>Message:</strong><br>'; if ($isHTML) { // 处理cid图片(需补充附件保存逻辑) $messageBody = preg_replace('/cid:([a-zA-Z0-9\-_]+)/', function($matches) use ($mailbox, $i) { // 示例占位,实际需匹配附件生成URL return $matches[0]; }, $messageBody); echo $messageBody; } else { echo nl2br(htmlspecialchars($messageBody)); } echo '<hr>'; } imap_close($mailbox); ?>
额外说明
- 图片加载:
cid:前缀指向邮件附件,需遍历邮件附件匹配cid,将附件保存到服务器后替换为可访问URL才能正常显示。 - Mustache模板使用:若需用模板渲染,需在模板中使用
{{{messageBody}}}(三个大括号表示不转义HTML),而非错误的style标签包裹。
内容的提问来源于stack exchange,提问作者Sargin
相关产品推荐
相关产品推荐

