You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP邮件附件异常排查:0KB、文件名错误及多附件显示问题

PHP邮件附件常见问题排查与解决

问题1:发送的附件始终为0KB

现象:已保留附件头与内容间的空行,但附件大小始终为0KB。
错误原因:循环中错误将文件原名存入数组,后续读取时用文件名而非临时文件路径,无法获取上传文件的实际内容。
错误代码片段:

for($i = 0; $i < count($_FILES['filename']['name']); $i++){
    $tmp_name = $_FILES['filename']['tmp_name'][$i];
    if (file_exists($tmp_name)){
        $fname[] = $_FILES['filename']['name'][$i];
    }
}

解决思路:需同时存储上传文件的临时路径和原文件名,临时路径用于读取文件内容,原文件名用于在邮件中显示正确的附件名称。

问题2:附件大小恢复正常,但文件名丢失后缀

现象:修改为存储临时路径后,附件大小正常,但接收端显示的文件名没有后缀。
原因:邮件头中未指定附件的原始文件名,默认使用无后缀的临时文件名。
解决方法:构建邮件附件部分时,通过Content-Disposition头指定filename参数,值为上传文件的原文件名。示例:

// 单个附件的头信息示例
$attachmentHeader = "Content-Disposition: attachment; filename=\"{$fname[$i]}\"\r\n";

问题3:仅第一个附件正常,其余附件显示为乱码文本

现象:分别存储临时路径和原文件名后,第一个附件显示正常,后续附件变成无意义的字母数字乱码。
常见原因及解决:

  • 边界(Boundary)处理错误:多附件邮件需用唯一边界字符串分隔每个部分,若循环中重复使用错误边界或未正确闭合附件块,会导致解析异常。
    解决:生成唯一边界字符串,每个附件块前后用--{$boundary}包裹,最后用--{$boundary}--结束所有附件。
  • 文件名编码问题:非ASCII文件名未按邮件标准编码,导致显示乱码。
    解决:将原文件名转换为RFC 2047格式编码,示例:
    $encodedFilename = '=?UTF-8?B?' . base64_encode($fname[$i]) . '?=';
    $attachmentHeader = "Content-Disposition: attachment; filename=\"{$encodedFilename}\"\r\n";
    
  • 文件内容读取与编码错误:循环读取文件时未重置文件指针,或未对文件内容进行base64编码。
    解决:读取每个附件时重新打开临时文件,读取后进行base64编码,示例:
    $fileContent = file_get_contents($fpath[$i]);
    $encodedContent = chunk_split(base64_encode($fileContent));
    

完整多附件邮件构建核心示例:

// 生成唯一边界
$boundary = md5(uniqid(time()));
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"{$boundary}\"\r\n";

// 构建邮件正文
$message = "--{$boundary}\r\n";
$message .= "Content-Type: text/plain; charset=UTF-8\r\n\r\n";
$message .= "邮件正文内容\r\n\r\n";

// 循环处理每个附件
for($i = 0; $i < count($fpath); $i++){
    $fileContent = file_get_contents($fpath[$i]);
    $encodedContent = chunk_split(base64_encode($fileContent));
    $encodedFilename = '=?UTF-8?B?' . base64_encode($fname[$i]) . '?=';
    
    $message .= "--{$boundary}\r\n";
    $message .= "Content-Type: application/octet-stream\r\n";
    $message .= "Content-Transfer-Encoding: base64\r\n";
    $message .= "Content-Disposition: attachment; filename=\"{$encodedFilename}\"\r\n\r\n";
    $message .= $encodedContent . "\r\n";
}

// 结束边界
$message .= "--{$boundary}--";

// 发送邮件
mail($to, $subject, $message, $headers);

内容的提问来源于stack exchange,提问作者fafa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 08:01:01