如何在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
相关产品推荐
相关产品推荐

