PHP文件上传同名确认覆盖后新文件无法上传问题求助
问题排查
整理你代码中的核心错误如下:
- 临时文件生命周期错误:PHP上传产生的临时文件仅存在于当前请求的生命周期内,当你输出确认表单、首次请求结束后,系统会自动删除该临时文件。你将临时文件路径存入隐藏域提交到二次请求时,对应文件已经不存在,
move_uploaded_file自然执行失败。 - 路径拼接错误:
$target_file本身已经是「上传目录+文件名」的完整路径,你后续又拼接了一次$_POST["replacefilename"],导致最终目标路径变成目录/文件名/文件名的错误格式。 - 逻辑分支位置错误:用户点击确认替换发起的是全新的HTTP请求,这次请求不会携带首次上传的文件,因此不会进入
file_exists($target_file)的判断分支,你写在该分支内的替换逻辑根本不会触发。 - 语法错误:
$last = str_replace('\\', '\', $last);转义逻辑存在语法错误,且该操作完全无必要。
修正方案
核心思路是首次检测到同名文件时,先将上传的临时文件转存到自定义临时目录,将临时文件路径、目标文件名存入session,再弹出确认框。用户提交确认后再从自定义临时目录读取文件完成替换操作:
<?php session_start(); $target_dir = "wp-content/themes/astra-child/myuploads/"; $temp_dir = $target_dir . "temp/"; // 需提前创建这个目录,给足PHP进程读写权限 $uploadOk = 1; // 处理替换确认请求 if (isset($_POST['btn-replace-yes'])) { if (!isset($_SESSION['temp_upload_path']) || !isset($_SESSION['target_file_name'])) { echo "请求已过期,请重新上传"; exit; } $temp_file = $_SESSION['temp_upload_path']; $target_file = $target_dir . $_SESSION['target_file_name']; // 删除旧文件 if (file_exists($target_file)) { unlink($target_file); } // 移动临时文件到目标目录 if (rename($temp_file, $target_file)) { echo "文件 «". htmlspecialchars($_SESSION['target_file_name']). "» 上传成功!"; // 清理session unset($_SESSION['temp_upload_path'], $_SESSION['target_file_name']); } else { echo "上传失败"; ?> <button onclick="window.location.href='secretary-panel';"> 返回 </button> <?php } exit; } elseif (isset($_POST['btn-replace-no'])) { // 清理临时文件和session if (isset($_SESSION['temp_upload_path']) && file_exists($_SESSION['temp_upload_path'])) { unlink($_SESSION['temp_upload_path']); } unset($_SESSION['temp_upload_path'], $_SESSION['target_file_name']); header("location:../secretary-panel/"); exit; } // 处理首次上传请求 if (isset($_FILES["fileToUpload"])) { $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]); if (file_exists($target_file)) { // 先把临时文件存到自定义临时目录 $temp_file_name = uniqid() . "_" . basename($_FILES["fileToUpload"]["name"]); $temp_save_path = $temp_dir . $temp_file_name; if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $temp_save_path)) { // 存session $_SESSION['temp_upload_path'] = $temp_save_path; $_SESSION['target_file_name'] = basename($_FILES["fileToUpload"]["name"]); // 输出确认表单 echo "文件已存在<br>"; echo "是否覆盖原有文件?"; ?> <form action="" method="post"> <input type="submit" value="是" name="btn-replace-yes"> <input type="submit" value="否" name="btn-replace-no"> </form> <?php } else { echo "临时文件保存失败,请重试"; } $uploadOk = 0; } // 无同名文件正常上传 if ($uploadOk == 1) { if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)){ echo "上传成功"; echo $_FILES["fileToUpload"]["tmp_name"];?><br><?php echo $target_file; } else { echo "上传失败";?> <button onclick="window.location.href='secretary-panel';"> 返回 </button> <?php } } } ?>
额外提示:建议增加文件名过滤、文件类型校验、文件大小限制等逻辑,避免恶意文件上传风险。
内容的提问来源于stack exchange,提问作者Scissors38th
相关产品推荐
相关产品推荐

