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

如何在PHP会话中存储文件?多页面表单上传故障求助

问题分析与解决方案

你碰到的核心问题是PHP的临时上传文件会在当前请求结束后自动删除——你把$_FILES里的tmp_name存到会话里,但切换页面(新的AJAX请求)后,原请求的临时文件已经被清理,最后提交时再调用move_uploaded_file自然找不到文件。

解决思路及步骤

1. 上传时立即转移临时文件

不要等到最后一步再处理文件,在用户上传文件的那个AJAX请求里,就把PHP生成的临时文件转移到项目内的持久化临时目录(比如/project/temp/),然后把这个新的文件路径存入会话,而不是原临时路径。

2. 修改上传处理逻辑

调整你的上传代码,在用户上传的请求中完成临时文件的转移:

// 先创建项目内的持久化临时目录(确保可写)
$temp_dir = $_SERVER["DOCUMENT_ROOT"]."/project/temp/";
if (!is_dir($temp_dir)) {
    mkdir($temp_dir, 0755, true);
}

// 生成唯一临时文件名,避免冲突
$temp_filename = uniqid() . '_' . basename($_FILES['relatorios-tecnicos']['name']);
$temp_file_path = $temp_dir . $temp_filename;

// 直接把上传的临时文件移到项目临时目录
if (move_uploaded_file($_FILES['relatorios-tecnicos']['tmp_name'], $temp_file_path)) {
    // 把持久化的临时路径和文件信息存到会话
    $_SESSION['support']['relatorios-tecnicos'] = [
        'name' => $_FILES['relatorios-tecnicos']['name'],
        'size' => $_FILES['relatorios-tecnicos']['size'],
        'temp_path' => $temp_file_path
    ];
    return "文件已暂存";
} else {
    return "文件暂存失败";
}

3. 最后提交时完成最终转移

当用户到最后一页提交表单时,从会话中取出持久化的临时文件路径,再移动到最终的uploads目录:

$target_dir = $_SERVER["DOCUMENT_ROOT"]."/project/uploads/";
$target_file = $target_dir . basename($_SESSION['support']['relatorios-tecnicos']['name']);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

// 保留你原有的校验逻辑
if (file_exists($target_file)) {
    return "Sorry, file already exists.";
    $uploadOk = 0;
}
if ($_SESSION['support']['relatorios-tecnicos']['size'] > 500000) {
    return "Sorry, your file is too large.";
    $uploadOk = 0;
}
if($imageFileType == "exe") {
    return "Sorry, we don't accept executables.";
    $uploadOk = 0;
}

if ($uploadOk == 0) {
    return "Sorry, your file was not uploaded.";
} else {
    try{
        if (is_dir($target_dir) && is_writable($target_dir)) {
            // 使用会话里的持久化临时路径
            if (rename($_SESSION['support']['relatorios-tecnicos']['temp_path'], $target_file)) {
                // 成功后清理临时文件(可选,也可定时清理)
                unlink($_SESSION['support']['relatorios-tecnicos']['temp_path']);
                return "文件上传成功";
            } else {
                return "文件转移失败";
            }
        } else {
            return '上传目录不存在或不可写: '.$target_dir;
        }
    }catch(Exception $e){
        return $e->getMessage();
    }
}

额外注意事项

  • 确保项目内的temp和uploads目录权限正确(设置为755或777,根据服务器配置调整)
  • 可添加定时清理脚本,定期删除temp目录中过期的暂存文件,避免占用空间
  • 你的页面切换逻辑(changePage函数)无需修改,只要保证上传文件时是通过AJAX提交到处理脚本即可

原代码问题说明

你之前的代码把$_FILES['relatorios-tecnicos']['tmp_name']存到会话,但这个路径仅在当前请求有效,请求结束后PHP会自动删除临时文件,跨请求后该路径指向的文件已不存在,因此move_uploaded_file执行失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:47:52