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

如何避免使用After Insert触发器后PHP库存系统出现负库存并添加提示?

库存出库系统负库存问题修复方案

原代码核心问题

  1. 变量名拼写错误:$tokavailable与判断用的$stokavailable不一致,导致库存判断逻辑完全颠倒
  2. 出库记录字段顺序错误:INSERT语句中nm_pegawai和stokk的参数位置写反,导致数据存储错乱
  3. 无参数校验:未检查必填项合法性,比如出库数量为负数的情况
  4. SQL注入风险:直接拼接用户输入到SQL语句中
  5. 无事务保障:出库记录和库存更新未绑定,可能出现数据不一致

修复后的完整代码

<?php
if($_SERVER['REQUEST_METHOD']=='POST') {
    date_default_timezone_set("Asia/Jakarta");
    $timestamp = date('H:i:s');
    $tanggal = date('Y-m-d');
    $response = array();

    // 获取并过滤POST参数
    $id_barang = isset($_POST['id_barang']) ? trim($_POST['id_barang']) : '';
    $nm_barang = isset($_POST['nm_barang']) ? trim($_POST['nm_barang']) : '';
    $stokk_keluar = isset($_POST['stokk']) ? intval($_POST['stokk']) : 0;
    $nm_pegawai = isset($_POST['nm_pegawai']) ? trim($_POST['nm_pegawai']) : '';

    // 基础参数校验
    if(empty($id_barang) || $stokk_keluar <= 0 || empty($nm_pegawai)) {
        $response["value"] = 0;
        $response["message"] = "参数错误,请检查输入";
        echo json_encode($response);
        exit;
    }

    require_once('dbConnect.php');  
    // 预处理查询库存,避免SQL注入
    $sql2 = "SELECT stokk FROM stok where id_barang=?";
    $stmt = mysqli_prepare($con, $sql2);
    mysqli_stmt_bind_param($stmt, "s", $id_barang);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);

    $stokavailable = 0;
    if($row = mysqli_fetch_assoc($res)){
        $stokavailable = intval($row['stokk']);
    } else {
        $response["value"] = 0;
        $response["message"] = "商品不存在";
        echo json_encode($response);
        mysqli_close($con);
        exit;
    }

    // 正确判断库存是否充足
    if($stokk_keluar > $stokavailable) {
        $response["value"] = 0;
        $response["message"] = "商品库存不足";
        echo json_encode($response);
    } else {
        // 开启事务,确保操作原子性
        mysqli_begin_transaction($con);
        try {
            // 修复字段顺序,插入出库记录
            $sql = "INSERT INTO keluar (id_barang, nm_barang, nm_pegawai, stokk, waktu, tanggal) 
                    VALUES(?, ?, ?, ?, ?, ?)";
            $stmt_insert = mysqli_prepare($con, $sql);
            mysqli_stmt_bind_param($stmt_insert, "ssssss", $id_barang, $nm_barang, $nm_pegawai, $stokk_keluar, $timestamp, $tanggal);
            
            if(mysqli_stmt_execute($stmt_insert)) {
                // 更新库存表(若触发器已处理库存更新,可删除此段)
                $sql_update = "UPDATE stok SET stokk = stokk - ? WHERE id_barang = ?";
                $stmt_update = mysqli_prepare($con, $sql_update);
                mysqli_stmt_bind_param($stmt_update, "is", $stokk_keluar, $id_barang);
                mysqli_stmt_execute($stmt_update);

                mysqli_commit($con);
                $response["value"] = 1;
                $response["message"] = "出库成功";
                echo json_encode($response);
            } else {
                throw new Exception("出库记录插入失败");
            }
        } catch(Exception $e) {
            mysqli_rollback($con);
            $response["value"] = 0;
            $response["message"] = "操作失败:".$e->getMessage();
            echo json_encode($response);
        }
    }
    mysqli_close($con);
}

关键优化说明

  • 修正库存判断逻辑:修复变量名拼写错误,将判断条件改为出库数量 > 可用库存时提示不足
  • 修复字段顺序:调整INSERT语句的参数对应关系,确保数据存储正确
  • 添加参数校验:拦截空参数、负数出库数量等无效请求
  • 防SQL注入:所有SQL操作使用mysqli预处理语句,避免用户输入篡改SQL
  • 事务处理:出库记录插入与库存更新绑定,任一操作失败则回滚,避免数据不一致
  • 异常场景处理:新增商品不存在的提示,避免未初始化变量报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 05:54:16