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

PHP脚本执行过快致大文件上传后无法正常邮件附加

解决PHP表单大文件上传后邮件附件丢失的问题

手动延迟脚本(比如sleep())是治标不治本的方案,核心要解决的是确保文件完全上传、ClamAV扫描完成后,再执行邮件附件逻辑,以下是具体的优化方案:

1. 检查并调整PHP上传相关配置

首先确保服务器允许大文件上传,修改php.ini中的以下参数(根据你的需求调整数值):

  • upload_max_filesize = 10M:允许上传的单个文件最大尺寸,需大于你要处理的最大文件
  • post_max_size = 12M:POST请求的最大总尺寸,必须大于upload_max_filesize
  • max_execution_time = 300:脚本最大执行时间,给大文件上传和扫描留足够时间
  • max_input_time = 300:接收POST数据的最大时间

修改后重启PHP服务生效。同时确认表单标签添加了enctype="multipart/form-data",否则无法上传文件。

2. 确保文件完全上传到服务器

不要直接使用临时文件进行扫描或附件操作,先通过move_uploaded_file()将文件从临时目录移动到指定存储目录,这个函数会确保文件完全上传完成后才执行移动操作。示例代码:

// 检查文件上传是否成功
if (isset($_FILES['uploaded_file']) && $_FILES['uploaded_file']['error'] === UPLOAD_ERR_OK) {
    $temp_path = $_FILES['uploaded_file']['tmp_name'];
    $target_dir = '/your/custom/upload/directory/';
    $original_filename = $_FILES['uploaded_file']['name'];
    $target_path = $target_dir . $original_filename;

    // 移动文件到目标目录,确认文件完整
    if (move_uploaded_file($temp_path, $target_path)) {
        // 后续扫描、重命名、邮件逻辑放在这里
    } else {
        die('文件上传失败:无法移动临时文件');
    }
} else {
    // 根据错误码处理上传失败情况
    switch ($_FILES['uploaded_file']['error']) {
        case UPLOAD_ERR_INI_SIZE:
            die('文件超过php.ini限制的最大尺寸');
        case UPLOAD_ERR_FORM_SIZE:
            die('文件超过表单设置的最大尺寸');
        default:
            die('文件上传失败,错误码:' . $_FILES['uploaded_file']['error']);
    }
}

3. 同步等待ClamAV扫描完成

如果通过命令行调用ClamAV(比如clamscan),必须等待扫描命令执行完毕再继续后续操作,避免异步导致的文件未处理完成。示例代码:

// 执行ClamAV扫描,等待命令返回结果
$scan_cmd = "clamscan --stdout " . escapeshellarg($target_path);
exec($scan_cmd, $scan_output, $return_code);

// 解析扫描结果:return_code为0表示无病毒,1表示发现病毒,其他值为扫描错误
if ($return_code === 0) {
    // 扫描通过,重命名文件
    $new_filename = 'safe_' . uniqid() . '_' . $original_filename;
    $new_file_path = $target_dir . $new_filename;
    if (rename($target_path, $new_file_path)) {
        // 这里执行邮件附件逻辑,使用$new_file_path作为附件路径
        send_email_with_attachment($new_file_path);
    } else {
        die('文件重命名失败');
    }
} else {
    // 扫描失败或发现病毒,删除文件
    unlink($target_path);
    die($return_code === 1 ? '文件包含病毒' : 'ClamAV扫描失败');
}

注意使用escapeshellarg()转义文件路径,避免命令注入风险。

4. 确保邮件发送逻辑的执行时机

将邮件发送代码严格放在文件上传成功、扫描通过、重命名完成的分支内,避免因代码分支错误导致提前发送邮件。

总结

手动sleep()只是掩盖了“未等待文件上传/扫描完成”的核心问题,通过调整PHP配置、确保文件完整上传、同步等待扫描完成,即可彻底解决大文件附件丢失的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:24:57