如何避免使用After Insert触发器后PHP库存系统出现负库存并添加提示?
库存出库系统负库存问题修复方案
原代码核心问题
- 变量名拼写错误:
$tokavailable与判断用的$stokavailable不一致,导致库存判断逻辑完全颠倒 - 出库记录字段顺序错误:
INSERT语句中nm_pegawai和stokk的参数位置写反,导致数据存储错乱 - 无参数校验:未检查必填项合法性,比如出库数量为负数的情况
- SQL注入风险:直接拼接用户输入到SQL语句中
- 无事务保障:出库记录和库存更新未绑定,可能出现数据不一致
修复后的完整代码
<?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
相关产品推荐
相关产品推荐

