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

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的合规图片:验证失效,仅存入名称
    超大小截图
  • 上传不合格式的图片:验证失效,仅存入名称
    不合格式截图

问题原因与修复方案

  1. 核心问题:无论图片验证是否通过,代码都会执行UPDATE语句,且直接将$cat_img_name(即使验证失败也存在文件名)赋值给$cat_img_to_insert,同时提前删除了旧图片,导致验证失效时错误的图片名称被存入数据库,旧图片也丢失。

  2. 修复步骤:

    • 先完成图片的所有验证,只有验证通过后才删除旧图片、移动新图片,否则保留旧图片不变。
    • 验证不通过时,终止更新流程,不执行数据库更新,仅提示错误信息。
    • 增加错误处理逻辑,确保验证失败时数据不被错误修改。

修复后的代码示例:

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;
    }
}
?>
  1. 额外优化建议:
  • 对文件扩展名转小写,避免因大小写(如PNG、JPG)导致的验证失败。
  • 删除旧图片前先检查文件是否存在,避免unlink()报错。
  • 重定向后使用exit终止脚本,防止后续代码执行。
  • 使用预处理语句(prepared statements)替代直接拼接SQL,防止SQL注入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:15:36