PHP图片上传:实现唯一命名及解决刷新重复上传问题
解决文件名唯一性与页面刷新重复上传问题
我来帮你搞定这两个头疼的问题,咱们先拆解问题,再一步步修改代码:
1. 生成唯一文件名的方案
你当前用的是用户上传的原文件名,很容易出现重名覆盖的情况。咱们可以结合uniqid()(生成唯一ID)+ 文件原扩展名来创建唯一文件名,这样就算多个用户上传同名文件也不会冲突了。
另外注意你代码里的几个小bug:
- 判断文件类型时用了未定义的
$name变量,应该分别检查$name1和$name2 - 移动文件时用了
$_FILES["img_url"]和$_FILES["img_urlz"],但表单字段名是img_url1和img_url2,这里对应错了
2. 解决页面刷新重复上传的问题
页面刷新重复上传是因为浏览器会重新发送上次的POST请求。咱们用PRG模式(Post/Redirect/Get):上传成功后,立即重定向到当前页面(或其他页面),这样页面刷新时只会发送GET请求,不会重复触发上传逻辑。
修改后的完整代码
<?php session_start(); // 记得开启session,原代码里可能遗漏了这一步 $video_type = trim($_GET['video_type']); if ($_SERVER["REQUEST_METHOD"] == "POST") { $target_dir = "pictures/"; // 确保目标目录存在,不存在则递归创建 if (!is_dir($target_dir)) { mkdir($target_dir, 0755, true); } // 处理第一张图片:生成唯一文件名 $name1 = $_FILES["img_url1"]["name"]; $ext1 = pathinfo($name1, PATHINFO_EXTENSION); $unique_name1 = uniqid('pic_', true) . '.' . $ext1; // 带前缀+高熵唯一ID+原扩展名 $target_file1 = $target_dir . $unique_name1; // 处理第二张图片:同样生成唯一文件名 $name2 = $_FILES["img_url2"]["name"]; $ext2 = pathinfo($name2, PATHINFO_EXTENSION); $unique_name2 = uniqid('pic_', true) . '.' . $ext2; $target_file2 = $target_dir . $unique_name2; // 统一验证文件类型(支持jpg/jpeg/png) $allowed_exts = ['jpg', 'jpeg', 'png']; $uploadOk = 1; if (!in_array(strtolower($ext1), $allowed_exts) || !in_array(strtolower($ext2), $allowed_exts)) { $uploadOk = 0; $_SESSION['error'] = "Sorry, only JPG, JPEG, PNG files are allowed."; } // 处理上传逻辑 if ($uploadOk == 0) { // 携带错误信息重定向 header("Location: " . $_SERVER['PHP_SELF'] . "?video_type=" . $video_type); exit; } else { // 修正字段名错误,移动上传文件 if (move_uploaded_file($_FILES["img_url1"]["tmp_name"], $target_file1) && move_uploaded_file($_FILES["img_url2"]["tmp_name"], $target_file2)) { // 插入数据库时用生成的唯一文件名,而非原文件名 $sql = "INSERT INTO picture (pic1, pic2, approved) VALUES ('$unique_name1', '$unique_name2' , 'false')"; if ($db->query($sql) === TRUE) { $_SESSION['success'] = 'Pictures uploaded successfully.'; } else { $_SESSION['error'] = $sql . "<br>" . $db->error; } } else { $_SESSION['error'] = "Sorry, there was an error uploading your files."; } // 无论成功失败,都重定向避免刷新重复提交 header("Location: " . $_SERVER['PHP_SELF'] . "?video_type=" . $video_type); exit; } } ?>
关键修改点说明
- 唯一文件名:用
uniqid('pic_', true)生成带前缀的高熵唯一ID,true参数会添加更多随机值,进一步降低重复概率 - 文件类型验证:改用
in_array统一检查允许的扩展名,逻辑更简洁且避免变量未定义的错误 - PRG模式:上传完成后通过
header("Location: ...")重定向,并用exit终止脚本,彻底避免刷新重复提交 - 目录检查:添加了目标目录的创建逻辑,避免因目录不存在导致上传失败
- 字段名修正:把
img_url/img_urlz改成了表单对应的img_url1/img_url2,修复了文件移动失败的潜在问题
内容的提问来源于stack exchange,提问作者Awais
相关产品推荐
相关产品推荐

