
本文介绍如何通过 SQL 的 UPDATE ... SET column = column + ? 语法,结合 PHP 预处理语句,安全、准确地对数据库中已有数值字段(如库存 inhouse)执行增量更新,避免 SQL 注入与逻辑错误。
本文介绍如何通过 sql 的 `update ... set column = column + ?` 语法,结合 php 预处理语句,安全、准确地对数据库中已有数值字段(如库存 inhouse)执行增量更新,避免 sql 注入与逻辑错误。
在实际业务场景中(例如库存管理),我们常需“在原有数值基础上增加新数量”,而非直接覆盖。例如:数据库中 inhouse = 15,用户提交新增数量 5,目标是将字段更新为 20。若错误地使用字符串拼接(如 "inhouse = '$new_quantity + $in'"),不仅语法无效(SQL 不会解析 PHP 变量表达式),更会引入严重安全风险。
✅ 正确做法是在 SQL 层直接完成加法运算,并严格使用预处理语句防止注入:
include("../../connection.php");
if (isset($_POST['update'])) {
$id = (int)$_POST['id']; // 强制类型转换,双重防护
$quantity_to_add = (int)$_POST['quantity'];
// ✅ 推荐:使用预处理语句(MySQLi 面向对象风格)
$stmt = $connections->prepare("UPDATE inv_tbl SET inhouse = inhouse + ? WHERE id = ?");
$stmt->bind_param("ii", $quantity_to_add, $id); // "ii" 表示两个整型参数
$stmt->execute();
// 可选:检查影响行数以确认更新成功
if ($stmt->affected_rows > 0) {
addLog($connections, "Added stock: +{$quantity_to_add} to item ID {$id}");
}
$stmt->close();
header("Location: ../stocks.php");
exit;
}
⚠️ 关键注意事项:
-
绝不拼接 SQL 字符串:原始代码中
"inhouse = '$new_quantity + $in'"是错误的——$in在 PHP 后端未定义(仅在前端 HTML 中存在),且单引号内变量不解析,最终执行的是字面量字符串,导致数据被破坏或 SQL 报错。 -
预处理语句是强制标准:
?占位符由 MySQL 驱动安全绑定,彻底杜绝 SQL 注入;同时明确指定参数类型(如"ii")可进一步增强健壮性。 -
前端无需传递原值:数据库自身完成
inhouse + ?计算,避免前后端数据不一致(如并发更新时竞态条件)。 -
补充防御性处理:对
$_POST数据做(int)类型转换,并用$stmt->affected_rows验证是否真实更新了记录,提升系统可观测性。
此外,在 HTML 模态框中,确保表单 action 指向正确的处理脚本(如 stocks/update-query.php),且隐藏域 已正确嵌入当前商品 ID —— 这是后端获取 $id 的唯一可靠来源。
掌握这一模式,你不仅能安全实现库存累加,还可推广至所有“原子性数值更新”场景(如积分增加、浏览量+1、余额充值等)。











