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

PHP发送邮件附件为空问题排查:附件大小0字节求解决

PHP发送带附件邮件附件为空(0字节)的问题排查与修复

核心问题分析

你的脚本附件为空(0字节),主要是文件读取环节的错误被掩盖,加上MIME格式不规范导致的,具体问题点如下:

  • 错误抑制符掩盖了文件读取失败:你用@前缀屏蔽了fopen、fread的错误信息,即便文件路径正确,若PHP没有读取该文件的权限,或者文件实际不存在,$data会被赋值为空,最终附件内容就是0字节。
  • MIME换行符不统一:邮件标准要求所有头信息和内容的换行必须用\r\n,你的脚本混合使用了\n和\r\n,可能导致邮件客户端解析附件时出错。
  • 重复调用filesize($file)且时机错误:第一次调用filesize时文件还没打开,若文件在两次调用期间被修改,会导致读取长度错误;更关键的是,若文件打开失败,filesize返回的数值会让fread读取无效内容。
  • Content-Disposition格式错误:size=".filesize($file)."不属于该字段的标准参数,多余的属性可能干扰邮件客户端解析附件。

修复后的脚本

$to = $destination; 
$from = 'test@test.test'; 
$fromName = 'Test'; 
$subject = $subject;
$file = "./image-based-pdf-sample.pdf";
$htmlContent = $content; 

// 先检查文件是否存在且可读
if (!file_exists($file) || !is_readable($file)) {
    die("<h1>Error: 文件不存在或无法读取</h1>");
}

$headers = "From: $fromName <$from>\r\n"; 

$semi_rand = md5(time());  
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";  

$headers .= "MIME-Version: 1.0\r\n" . 
            "Content-Type: multipart/mixed;\r\n" . 
            " boundary=\"{$mime_boundary}\"\r\n"; 

$message = "--{$mime_boundary}\r\n" . 
           "Content-Type: text/html; charset=\"UTF-8\"\r\n" . 
           "Content-Transfer-Encoding: 7bit\r\n\r\n" . 
           $htmlContent . "\r\n";  

$message .= "--{$mime_boundary}\r\n"; 
$fp = fopen($file,"rb"); 
if (!$fp) {
    die("<h1>Error: 无法打开文件</h1>");
}
// 通过fstat获取打开文件的大小,避免文件变化问题
$fileStat = fstat($fp);
$data = fread($fp, $fileStat['size']); 

fclose($fp); 
$data = chunk_split(base64_encode($data)); 
$message .= "Content-Type: application/octet-stream; name=\"".basename($file)."\"\r\n" .  
            "Content-Description: ".basename($file)."\r\n" . 
            "Content-Disposition: attachment;\r\n" . 
            " filename=\"".basename($file)."\"\r\n" .  
            "Content-Transfer-Encoding: base64\r\n\r\n" . 
            $data . "\r\n"; 

$message .= "--{$mime_boundary}--"; 
$returnpath = "-f" . $from; 

$mail = mail($to, $subject, $message, $headers, $returnpath);  

echo $mail?"<h1>Success</h1>":"<h1>Error</h1>"; 

关键修复点说明

  1. 添加文件存在性和可读性检查:提前判断文件状态,避免后续无意义的操作。
  2. 移除错误抑制符并添加打开失败检查:暴露文件读取的真实问题,方便排查。
  3. 统一使用\r\n作为换行符:符合MIME邮件标准,避免解析错误。
  4. 用fstat获取已打开文件的大小:确保读取长度准确,不受文件外部修改影响。
  5. 移除Content-Disposition中的多余size参数:遵循标准格式,避免解析干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:55:17