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

PHP多附件邮件发送异常:仅收到最后一个附件求助

问题:PHP发送多附件邮件仅收到最后一个文件

通过POST API(Postman form-data提交)接收4个附件,调用PHP的mail()函数发送邮件,但仅能收到最后一个附件。已开启错误报告:

error_reporting(-1);
ini_set('display_errors', 'On');

错误日志无报错,原代码存在结构逻辑问题,导致邮件内容被覆盖、MIME格式混乱。


问题根源

  1. 重复生成MIME边界:每个附件处理时都重新创建新的MIME边界,多次向$headers添加MIME头部,破坏邮件结构。
  2. 覆盖消息体变量:处理第二个附件时用$message =直接赋值,覆盖了之前的文本内容和第一个附件数据,最终仅保留最后一个附件。
  3. 不符合MIME规范:多附件邮件需使用同一个边界分隔所有内容(文本+多个附件),而非每个附件单独创建边界。

修正后的完整代码

<?php
error_reporting(-1);
ini_set('display_errors', 'On');

if ($_POST) {
    $name        = "Name goes here";
    $email       = "seshuvardhan456@gmail.com";
    $to          = "$name <$email>";
    $from        = "Gyan-Shah";
    $subject     = "Here is your attachment";
    
    // 构建文本内容
    $mainMessage = "Hi,\nBelow are the Details:\n" .
                   "Name: '" . $_POST['fullname'] . "'\n" .
                   "Date Of Birth: '" . $_POST['dob'] . "'\n" .
                   "Phone Number: '" . $_POST['phone_number'] . "'\n" .
                   "Email: '" . $_POST['email'] . "'\n" .
                   "Address: '" . $_POST['address'] . "'\n" .
                   "Father Name: '" . $_POST['father_name'] . "'\n" .
                   "Mother Name: '" . $_POST['mother_name'] . "'\n" .
                   "Work Experience: '" . $_POST['work_experience'] . "'\n" .
                   "Education: '" . $_POST['education'] . "'\n" .
                   "Skills: '" . $_POST['skills'] . "'\n";

    // 初始化邮件头部与唯一MIME边界
    $semi_rand     = md5(time());
    $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
    $headers       = "From: $from\r\n";
    $headers      .= "MIME-Version: 1.0\r\n";
    $headers      .= "Content-Type: multipart/mixed;\r\n boundary=\"{$mime_boundary}\"";

    // 初始化消息体:文本部分
    $message = "This is a multi-part message in MIME format.\r\n\r\n";
    $message .= "--{$mime_boundary}\r\n";
    $message .= "Content-Type: text/plain; charset=\"iso-8859-1\"\r\n";
    $message .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
    $message .= $mainMessage . "\r\n\r\n";

    // 处理第一个附件:照片
    if (isset($_FILES['photo']) && $_FILES['photo']['error'] == UPLOAD_ERR_OK) {
        $tmp_name = $_FILES['photo']['tmp_name'];
        $name     = $_FILES['photo']['name'];
        $size     = $_FILES['photo']['size'];
        $type     = $_FILES['photo']['type'];

        $handle = fopen($tmp_name, "r");
        $content = fread($handle, $size);
        fclose($handle);

        $data = chunk_split(base64_encode($content));
        $message .= "--{$mime_boundary}\r\n";
        $message .= "Content-Type: {$type};\r\n name=\"{$name}\"\r\n";
        $message .= "Content-Disposition: attachment;\r\n filename=\"{$name}\"\r\n";
        $message .= "Content-Transfer-Encoding: base64\r\n\r\n";
        $message .= $data . "\r\n\r\n";
    }

    // 处理第二个附件:护照首页
    if (isset($_FILES['passport_front']) && $_FILES['passport_front']['error'] == UPLOAD_ERR_OK) {
        $tmp_name_p_f = $_FILES['passport_front']['tmp_name'];
        $name_p_f     = $_FILES['passport_front']['name'];
        $size_p_f     = $_FILES['passport_front']['size'];
        $type_p_f     = $_FILES['passport_front']['type'];

        $handle_p_f = fopen($tmp_name_p_f, "r");
        $content_p_f = fread($handle_p_f, $size_p_f);
        fclose($handle_p_f);

        $data_p_f = chunk_split(base64_encode($content_p_f));
        $message .= "--{$mime_boundary}\r\n";
        $message .= "Content-Type: {$type_p_f};\r\n name=\"{$name_p_f}\"\r\n";
        $message .= "Content-Disposition: attachment;\r\n filename=\"{$name_p_f}\"\r\n";
        $message .= "Content-Transfer-Encoding: base64\r\n\r\n";
        $message .= $data_p_f . "\r\n\r\n";
    }

    // 处理剩余两个附件(请替换为实际字段名)
    // if (isset($_FILES['xxx']) && $_FILES['xxx']['error'] == UPLOAD_ERR_OK) {
    //     // 重复上述附件处理逻辑
    // }

    // 结束MIME边界
    $message .= "--{$mime_boundary}--\r\n";

    // 发送邮件
    if (mail($to, $subject, $message, $headers)) {
        echo "The email was sent.";
    } else {
        echo "There was an error sending the mail.";
    }
}
?>

关键改进说明

  • 统一MIME边界:仅生成一个唯一边界,所有内容通过该边界分隔,符合邮件MIME规范。
  • 追加消息体:使用$message .=追加附件内容,避免覆盖之前的文本和附件数据。
  • 规范换行符:使用\r\n作为邮件头部和消息体的换行符,符合RFC邮件标准。
  • 上传校验:通过UPLOAD_ERR_OK判断文件是否上传成功,避免处理无效文件。
  • 模块化扩展:每个附件的处理逻辑独立,方便添加更多附件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 08:25:35