PHP发送带PDF附件邮件时MIME边界被识别为正文问题
解决PHP发送带PDF附件邮件时MIME边界不被识别的问题
你的代码存在几个MIME格式的关键错误,导致邮件客户端无法正确解析边界和附件,以下是问题点和修正方案:
问题分析
- 换行符不统一:邮件MIME协议强制要求所有头部和正文的换行必须使用
\r\n,你代码里混合使用了\n和\r\n,破坏了邮件结构。 - Content-Transfer-Encoding行格式错误:你把
base64声明和编码后的文件内容直接拼接在一起,没有换行和分隔空行,客户端无法区分协议头和附件内容。 - 边界定义的格式问题:头部中
boundary参数的换行和空格处理不规范,可能导致客户端无法识别边界字符串。
修正后的代码
$home = $_SERVER['DOCUMENT_ROOT']; $hostUrl = 'https://my-domain.com'; $tmpName = $_FILES['file']['tmp_name']; $result = time().'-'.substr(sha1(mt_rand()),0,10); $target = "/uploaded-files/".$result.".pdf"; $filePath = $home.$target; $fileUrl = $hostUrl.$target; move_uploaded_file($tmpName, $filePath); $textMsg = '<p>Hi! Kanayo Austin</p>'; $textMsg .= '<p>Your request to print your JAMB Result Slip was successful and below is a PDF attachment of your JAMB Result Slip.</p>'; $textMsg .= '<p>You can also login to your account to download your JAMB Result Slip<a href="https://my-domain.com/login/">Login</a></p>'; $textMsg .= '<p>Need to access more of our services? <a href="https://my-domain.com/">Access More</a></p>'; $subject = "JAMB Result Slip"; $templateUrl = $hostUrl.'/mail-templates/default.php?title='.urlencode($subject).'&text='.urlencode($textMsg); $msg = file_get_contents($templateUrl, true); $file = fopen($filePath, 'rb'); $fileContent = fread($file, filesize($filePath)); fclose($file); $data = chunk_split(base64_encode($fileContent)); $separator = md5(time()); $mimeBoundary = "==Multipart_Boundary_x{$separator}x"; // 修正头部:统一换行符,规范boundary格式 $headers = "From: Grafil Computers <noreply@grafil-computers.com>\r\n"; $headers .= "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: multipart/mixed; boundary=\"{$mimeBoundary}\"\r\n"; // 修正正文:所有换行用\r\n,修复Content-Transfer-Encoding行 $message = "--{$mimeBoundary}\r\n"; $message .= "Content-Type: text/html; charset=\"UTF-8\"\r\n"; $message .= "Content-Transfer-Encoding: 7bit\r\n\r\n"; $message .= $msg . "\r\n"; $message .= "--{$mimeBoundary}\r\n"; $message .= "Content-Type: application/pdf; name=\"Result-Slip.pdf\"\r\n"; $message .= "Content-Disposition: attachment; filename=\"Result-Slip.pdf\"\r\n"; $message .= "Content-Transfer-Encoding: base64\r\n\r\n"; $message .= $data . "\r\n"; $message .= "--{$mimeBoundary}--\r\n"; mail('name@email.com', $subject, $message, $headers);
关键修改说明
- 统一换行符:所有头部和正文的换行全部替换为
\r\n,严格符合MIME标准。 - 修复附件编码行:将
Content-Transfer-Encoding: base64和附件内容分开,中间添加\r\n\r\n作为分隔,让客户端能正确识别附件内容的起始位置。 - 规范头部格式:调整
Content-Type行的格式,去掉多余空格,确保boundary参数被正确解析。
内容的提问来源于stack exchange,提问作者KANAYO AUGUSTIN UG
相关产品推荐
相关产品推荐

