为什么使用PHP的mail()函数发送两个附件仅能收到第一个?
问题原因
你代码的核心错误是第二个附件块前未添加MIME分隔标记,按照MIME邮件规范,每一个独立的内容单元(正文、每个附件)都必须以--[分隔符]开头,你只在第一个附件前加了分隔符,第二个附件直接拼接在第一个附件内容之后,邮件客户端会把第二个附件的所有内容识别为第一个附件的一部分,自然只能看到第一个附件。
另外还有两处不符合MIME规范的细节也可能导致解析异常:
- 你把MIME预提示文字
This is a MIME encoded message.写进了请求头里,这段文字应该放在邮件正文的最开头,不属于header内容 - 每个内容单元的头部配置和实际内容之间需要空一行(多拼接一个
$eol),否则部分严格的邮件客户端会解析失败
修复步骤
- 在第二个附件的
Content-Type配置前添加分隔符行 - 把预提示文字从header移到body开头
- 每个内容单元的头部和内容之间补充空行
修复后完整代码
$from = "postmaster@localhost"; // $to = "hector.oscos@gmail.com"; $content = file_get_contents($file1); $content2 = file_get_contents($file2); $content = chunk_split(base64_encode($content)); $content2 = chunk_split(base64_encode($content2)); // 生成随机分隔符用于区分混合内容 $semi_rand = md5(time()); $separator = "==Multipart_Boundary_x{$semi_rand}x"; // 换行符统一使用\r\n符合邮件规范 $eol = "\r\n"; // 主请求头 $headers = "From: Name<" . $from . ">" . $eol; $headers .= "MIME-Version: 1.0" . $eol; $headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol; $headers .= "Content-Transfer-Encoding: 7bit" . $eol; // 邮件正文开头先加MIME预提示,不支持MIME的客户端会显示这段文字 $body = "This is a MIME encoded message." . $eol; // 正文内容块 $body .= "--" . $separator . $eol; $body .= "Content-Type: text/html;" . $eol; $body .= "Content-Transfer-Encoding: 8bit" . $eol . $eol; // 头部和内容之间加空行 $body .= $message . $eol; // 第一个附件块 $body .= "--" . $separator . $eol; $body .= "Content-Type: application/octet-stream; name=\"factura.pdf\"" . $eol; $body .= "Content-Transfer-Encoding: base64" . $eol; $body .= "Content-Disposition: attachment; filename=\"factura.pdf\"" . $eol; $body .= "X-Attachment-Id: " . rand(1000, 99999) . $eol . $eol; // 头部和内容之间加空行 $body .= $content . $eol; // 第二个附件块:添加分隔符 $body .= "--" . $separator . $eol; $body .= "Content-Type: application/octet-stream; name=\"factura.xml\"" . $eol; $body .= "Content-Transfer-Encoding: base64" . $eol; $body .= "Content-Disposition: attachment; filename=\"factura.xml\"" . $eol; $body .= "X-Attachment-Id: " . rand(1000, 99999) . $eol . $eol; // 头部和内容之间加空行 $body .= $content2 . $eol; // 结束分隔符 $body .= "--" . $separator . "--"; // 发送邮件 mail($to, $subject, $body, $headers);
内容的提问来源于stack exchange,提问作者Héctor Oscós
相关产品推荐
相关产品推荐

