
本文介绍如何在 PHP 中安全地检查数据库中是否已存在同名操作记录,并通过唯一约束与 ON DUPLICATE KEY UPDATE 实现防重插入或自动更新,同时彻底规避 SQL 注入风险。
本文介绍如何在 php 中安全地检查数据库中是否已存在同名操作记录,并通过唯一约束与 `on duplicate key update` 实现防重插入或自动更新,同时彻底规避 sql 注入风险。
在开发后台管理功能(如添加手术项目)时,仅执行无条件 INSERT 会导致重复数据污染数据库,既影响业务逻辑准确性,也违背数据完整性原则。解决该问题不能依赖应用层“先查后插”(race condition 风险高),而应结合数据库约束与安全的 SQL 写法。
✅ 正确做法:数据库层强制约束 + 原子化 SQL 操作
首先,确保数据库表结构已为 operationname 字段添加唯一约束(推荐设为主键或添加 UNIQUE 索引):
ALTER TABLE operation ADD UNIQUE KEY uk_operationname (operationname); -- 或若该字段适合作为主键(无 NULL、不变更): -- ALTER TABLE operation DROP PRIMARY KEY, ADD PRIMARY KEY (operationname);
随后,在 PHP 中使用 预处理语句(Prepared Statements) 执行带冲突处理的插入操作,避免字符串拼接带来的 SQL 注入漏洞:
<?php
include('db_conn.php');
// 获取并过滤输入(基础净化)
$operationname = trim($_POST['operationname'] ?? '');
$cost = floatval($_POST['cost'] ?? 0);
// 验证必要字段
if (empty($operationname)) {
echo json_encode(['status' => 'failed', 'message' => '操作名称不能为空']);
exit;
}
// 使用 ON DUPLICATE KEY UPDATE 实现“存在则更新,不存在则插入”
$sql = "INSERT INTO operation(operationname, cost) VALUES(?, ?)
ON DUPLICATE KEY UPDATE cost = VALUES(cost)";
$stmt = mysqli_prepare($con, $sql);
if (!$stmt) {
echo json_encode(['status' => 'failed', 'message' => 'SQL 准备失败:' . mysqli_error($con)]);
exit;
}
mysqli_stmt_bind_param($stmt, 'sd', $operationname, $cost);
$result = mysqli_stmt_execute($stmt);
if ($result) {
// affected_rows > 0 表示新增;= 0 表示因重复而更新(MySQL 特性)
$affected = mysqli_stmt_affected_rows($stmt);
$status = $affected > 0 ? 'success_inserted' : 'success_updated';
echo json_encode(['status' => $status, 'operationname' => $operationname]);
} else {
echo json_encode(['status' => 'failed', 'message' => '数据库操作失败:' . mysqli_error($con)]);
}
mysqli_stmt_close($stmt);
?>⚠️ 关键注意事项
-
绝不拼接 SQL:原始代码中直接将
$_POST变量嵌入 SQL 字符串,是典型的 SQL 注入入口,攻击者可借此删除表、窃取数据。 -
唯一约束是前提:
ON DUPLICATE KEY UPDATE仅在存在PRIMARY KEY或UNIQUE INDEX时生效,务必提前在数据库中配置。 -
区分插入与更新语义:可通过
mysqli_stmt_affected_rows()判断本次操作是新增记录(返回 1)还是更新已有记录(返回 2,MySQL 8.0+ 默认行为),便于前端反馈不同提示。 -
输入校验不可省略:即使使用预处理,仍需对
operationname做非空/长度校验,对cost做数值类型转换,提升系统健壮性。
综上,通过「数据库唯一约束 + 预处理语句 + ON DUPLICATE KEY UPDATE」三位一体方案,既能高效防止重复数据,又能保障安全性与事务原子性,是生产环境推荐的标准实践。


















