PHP分类CRUD更新操作中图片验证失效问题求助
分类CRUD更新操作的图片上传验证问题
我是PHP Web开发新手,正在制作一个包含商品和分类的简单网站,在分类的CRUD更新操作上传图片时遇到问题:上传小于2MB的合规图片时,更新正常且旧图片会被删除;但当图片超过2MB或格式不符合允许的类型时,验证失效,仅图片名称被存入数据库。以下是我的代码,附上结果截图:
include("../config/dbconn.php"); if (isset($_POST['update'])) { $cat_id = mysqli_real_escape_string($dbconn, $_POST['cat_id']); $cat_name = mysqli_real_escape_string($dbconn, $_POST['cat_name']); $pervious_cat_name = filter_var($_POST['pervious_cat_name'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); $cat_img = $_FILES['cat_img']; // checking empty fields if (empty($cat_name) || empty($cat_img)) { if (empty($cat_name)) { echo "<font color='red'>category name field is empty!</font><br/>"; } if (empty($cat_img)) { echo "<font color='red'>image field is empty!</font><br/>"; } } else { //updating the table if ($cat_img['name']) { $pervious_cat_path = '../../uploads/' . $pervious_cat_name; if ($pervious_cat_path) { unlink($pervious_cat_path); } $cat_img_name = $cat_img['name']; $cat_temp_name = $cat_img['tmp_name']; $cat_img_destination_path = '../../uploads/' . $cat_img_name; $allow_files = ['png', 'jpg', 'jpeg','webp']; $extension = explode('.', $cat_img_name); $extension = end($extension); if (in_array($extension, $allow_files)) { if ($cat_img['size'] < 2000000) { move_uploaded_file($cat_temp_name, $cat_img_destination_path); } else { $_SESSION['category_update'] = "couldn't update category, image size is too large"; } } else { $_SESSION['category_update'] = "couldn't update category, image should be png, jpg, jpeg"; } } $cat_img_to_insert = $cat_img_name ?? $pervious_cat_name; $query = "UPDATE category SET cat_name='$cat_name', cat_img='$cat_img_to_insert' WHERE cat_id=$cat_id"; $result = mysqli_query($dbconn, $query); if ($result) { //redirecting to the display page. In our case, it is index.php header("Location: admin_panel.php"); } } } ?>
结果截图说明
- 上传小于2MB的合规图片:正常更新

- 上传大于2MB的合规图片:验证失效,仅存入名称

- 上传不合格式的图片:验证失效,仅存入名称

问题原因与修复方案
核心问题:无论图片验证是否通过,代码都会执行UPDATE语句,且直接将
$cat_img_name(即使验证失败也存在文件名)赋值给$cat_img_to_insert,同时提前删除了旧图片,导致验证失效时错误的图片名称被存入数据库,旧图片也丢失。修复步骤:
- 先完成图片的所有验证,只有验证通过后才删除旧图片、移动新图片,否则保留旧图片不变。
- 验证不通过时,终止更新流程,不执行数据库更新,仅提示错误信息。
- 增加错误处理逻辑,确保验证失败时数据不被错误修改。
修复后的代码示例:
include("../config/dbconn.php"); session_start(); // 确保session已启动 if (isset($_POST['update'])) { $cat_id = mysqli_real_escape_string($dbconn, $_POST['cat_id']); $cat_name = mysqli_real_escape_string($dbconn, $_POST['cat_name']); $pervious_cat_name = filter_var($_POST['pervious_cat_name'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); $cat_img = $_FILES['cat_img']; $update_success = false; $cat_img_to_insert = $pervious_cat_name; // 默认保留旧图片 // 检查分类名称是否为空 if (empty($cat_name)) { echo "<font color='red'>分类名称字段不能为空!</font><br/>"; } else { // 处理图片上传(如果有新图片) if (!empty($cat_img['name'])) { $cat_img_name = $cat_img['name']; $cat_temp_name = $cat_img['tmp_name']; $cat_img_destination_path = '../../uploads/' . $cat_img_name; $allow_files = ['png', 'jpg', 'jpeg','webp']; $extension = strtolower(end(explode('.', $cat_img_name))); // 统一转小写避免大小写问题 // 验证图片格式和大小 if (!in_array($extension, $allow_files)) { $_SESSION['category_update'] = "无法更新分类,图片格式必须是png、jpg、jpeg或webp"; } elseif ($cat_img['size'] >= 2000000) { $_SESSION['category_update'] = "无法更新分类,图片大小不能超过2MB"; } else { // 验证通过,删除旧图片并移动新图片 $pervious_cat_path = '../../uploads/' . $pervious_cat_name; if (file_exists($pervious_cat_path)) { // 检查文件是否存在再删除 unlink($pervious_cat_path); } if (move_uploaded_file($cat_temp_name, $cat_img_destination_path)) { $cat_img_to_insert = $cat_img_name; $update_success = true; } else { $_SESSION['category_update'] = "图片上传失败,请重试"; } } } else { // 没有上传新图片,只更新分类名称 $update_success = true; } // 只有验证通过时才执行更新 if ($update_success) { $query = "UPDATE category SET cat_name='$cat_name', cat_img='$cat_img_to_insert' WHERE cat_id=$cat_id"; if (mysqli_query($dbconn, $query)) { $_SESSION['category_update'] = "分类更新成功"; header("Location: admin_panel.php"); exit; // 重定向后终止脚本 } else { $_SESSION['category_update'] = "数据库更新失败:" . mysqli_error($dbconn); } } // 如果有错误,跳回表单页面或显示错误 header("Location: your_category_edit_page.php"); // 替换为你的编辑页面路径 exit; } } ?>
- 额外优化建议:
- 对文件扩展名转小写,避免因大小写(如PNG、JPG)导致的验证失败。
- 删除旧图片前先检查文件是否存在,避免
unlink()报错。 - 重定向后使用
exit终止脚本,防止后续代码执行。 - 使用预处理语句(prepared statements)替代直接拼接SQL,防止SQL注入。
内容的提问来源于stack exchange,提问作者yazan_bader
相关产品推荐
相关产品推荐

