如何配置PHP mail函数Header以同时支持HTML内容与附件?
解决PHP mail()同时支持HTML内容和附件的Header配置问题
你的代码里有两个关键问题导致HTML和附件无法同时生效:
- 重复声明了
MIME-Version头,虽然不会报错但属于冗余配置 - 同时设置了
text/html和multipart/mixed两种Content-Type——这会让邮件客户端混淆解析规则,因为带附件的邮件必须以multipart/mixed作为顶级Content-Type,HTML内容需要作为其中一个独立的部分存在。
下面是正确的实现思路和代码示例:
核心原理
带附件的HTML邮件需要采用多层MIME结构:
- 顶级类型是
multipart/mixed,用来分隔邮件正文部分和附件部分 - 正文部分使用
multipart/alternative,同时提供纯文本版本(兼容不支持HTML的邮件客户端)和HTML版本 - 每个部分都要用唯一的boundary字符串分隔,确保邮件客户端能正确识别各个模块
完整代码示例
// 定义分隔符:主分隔符(区分正文和附件)、子分隔符(区分纯文本和HTML) $main_boundary = '----MainBoundary'.md5(time()); $alt_boundary = '----AltBoundary'.md5(time()); // 基础邮件头 $headers = "MIME-Version: 1.0\r\n"; $headers .= "From: EITA <your-email@example.com>\r\n"; // 建议加上邮箱地址,提升投递成功率 $headers .= "Reply-To: EITA <reply-email@example.com>\r\n"; // 顶级Content-Type:multipart/mixed,指定主分隔符 $headers .= "Content-Type: multipart/mixed; boundary=\"$main_boundary\"\r\n\r\n"; // 第一部分:邮件正文(包含纯文本和HTML) $headers .= "--$main_boundary\r\n"; $headers .= "Content-Type: multipart/alternative; boundary=\"$alt_boundary\"\r\n\r\n"; // 纯文本版本(兼容低版本客户端) $headers .= "--$alt_boundary\r\n"; $headers .= "Content-Type: text/plain; charset=iso-8859-1\r\n"; $headers .= "Content-Transfer-Encoding: 7bit\r\n\r\n"; $plain_text_content = "这是纯文本版本的邮件内容,供不支持HTML的客户端查看\r\n"; $headers .= $plain_text_content . "\r\n\r\n"; // HTML版本 $headers .= "--$alt_boundary\r\n"; $headers .= "Content-Type: text/html; charset=iso-8859-1\r\n"; $headers .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n"; $html_content = "<html><body><h1>HTML邮件标题</h1><p>这是HTML格式的邮件内容</p></body></html>\r\n"; $headers .= $html_content . "\r\n\r\n"; // 结束正文部分的子分隔符 $headers .= "--$alt_boundary--\r\n\r\n"; // 第二部分:添加附件(示例为本地文件) $file_path = './test.pdf'; $file_name = '测试文件.pdf'; $file_content = file_get_contents($file_path); $file_encoded = chunk_split(base64_encode($file_content)); $headers .= "--$main_boundary\r\n"; $headers .= "Content-Type: application/pdf; name=\"$file_name\"\r\n"; $headers .= "Content-Disposition: attachment; filename=\"$file_name\"\r\n"; $headers .= "Content-Transfer-Encoding: base64\r\n\r\n"; $headers .= $file_encoded . "\r\n\r\n"; // 结束主分隔符 $headers .= "--$main_boundary--\r\n"; // 发送邮件 $to = 'recipient@example.com'; $subject = '带HTML内容和附件的测试邮件'; mail($to, $subject, '', $headers); // 注意这里第三个参数留空,因为内容已经包含在headers里了
关键注意事项
- boundary必须唯一:建议用时间戳+md5生成,避免和邮件内容冲突
- 必须严格遵守换行规则:每个头信息结束用
\r\n,部分之间的空行(\r\n\r\n)是MIME结构的必要分隔符 - 添加纯文本版本:虽然你需要HTML格式,但纯文本版本能提升邮件的兼容性和投递成功率
- 附件编码:必须用base64编码,并用
chunk_split拆分成长度合适的行
内容的提问来源于stack exchange,提问作者Safa Jwd
相关产品推荐
相关产品推荐

