




本文详解 php 手动构造 multipart mime 邮件时的常见陷阱,重点解决 apple mail 显示空白、仅显示最后一张图等问题,通过嵌套 multipart/related + multipart/alternative 结构实现跨平台(ios/android/web)稳定渲染。
Apple Mail 对 MIME 结构的解析比大多数客户端更严格——它不支持在 multipart/alternative 中直接混排图像部分与 HTML 部分,也不接受 Content-ID 引用但未被正确包裹在 multipart/related 子边界内的内联图片。你原始代码的问题根源在于:单一层级的 multipart/alternative 无法承载内嵌资源(如 CID 引用的图片),导致 iOS 客户端忽略或错误解析整个 HTML 体,最终呈现为空白或仅最后一张图。
必须采用两层边界嵌套:
以下是可直接落地的修正方案(已验证在 Apple Mail、Outlook iOS、Gmail App、Thunderbird 和桌面浏览器中一致显示):
$boundary = md5(uniqid(rand())); // 全局唯一边界标识
$outerBoundary = 'b1_' . $boundary;
$innerBoundary = 'b2_' . $boundary;
// ✅ 外层 headers:声明 multipart/alternative + 外边界
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/alternative; boundary=\"{$outerBoundary}\"\r\n";
$headers .= "From: \r\n";
$headers .= "Reply-To: no-reply@yourdomain.net\r\n";
// ✅ 构建完整邮件体(注意顺序与换行!)
$message = "";
// ▶ 第一部分:纯文本备选(Apple Mail 会忽略,但规范要求存在)
$message .= "--{$outerBoundary}\r\n";
$message .= "Content-Type: text/plain; charset=\"us-ascii\"\r\n";
$message .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$message .= "This email contains a visitor register with photos. Please view in HTML mode.\r\n\r\n";
// ▶ 第二部分:HTML 主体(类型为 multipart/related)
$message .= "--{$outerBoundary}\r\n";
$message .= "Content-Type: multipart/related; boundary=\"{$innerBoundary}\"; type=\"text/html\"\r\n\r\n";
// ▶ 内层 HTML 内容(注意:此处不写 --b2_xxx,由下一行开始)
$message .= "--{$innerBoundary}\r\n";
$message .= "Content-Type: text/html; charset=\"UTF-8\"\r\n";
$message .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
// 插入你的完整 HTML(含 @@##@@)
$message .= $mailHeader;
$message .= "Visitors on " . date("d/m/Y", strtotime($_POST['date'])) . "
";
$message .= $table;
$message .= $mailFooter;
$message .= "\r\n";
// ▶ 内层图片资源(每个图片必须在 --b2_xxx 边界内,且 Content-ID 严格匹配 HTML 中的 cid:xxx)
foreach ($images as $imgData) {
$imageName = $imgData['name']; // e.g., 'Robin0'
$imageBase64 = $imgData['base64']; // 原始 base64 字符串(
不含 data:...)
$message .= "--{$innerBoundary}\r\n";
$message .= "Content-Type: image/jpeg; name=\"{$imageName}.jpg\"\r\n"; // ⚠️ 用 image/jpeg 而非 image/jpg(更标准)
$message .= "Content-Transfer-Encoding: base64\r\n";
$message .= "Content-ID: <{$imageName}>\r\n";
$message .= "Content-Disposition: inline; filename=\"{$imageName}.jpg\"\r\n\r\n";
$message .= chunk_split($imageBase64, 76, "\r\n"); // ✅ 每行 ≤76 字符,符合 RFC 2045
}
// ▶ 结束内层 multipart/related
$message .= "--{$innerBoundary}--\r\n";
// ▶ 结束外层 multipart/alternative
$message .= "--{$outerBoundary}--\r\n";
// 发送
mail($to, $subject, $message, $headers); 发送测试邮件后,在 Apple Mail 中:
通过该结构,你将彻底规避 Apple Mail 的渲染缺陷,同时保持 Android、Web 客户端完美兼容——无需引入 PHPMailer 等依赖,纯原生 PHP 即可稳定交付专业级 HTML 邮件。