最根本的防护方法是使用预处理和参数化查询,通过将sql指令与数据彻底分离,避免恶意字符影响sql结构;php中用pdo或mysqli::prepare,java用preparedstatement,python用参数化execute,均能确保用户输入仅作纯参数处理。

识别 mysql_query + 字符串拼接的典型模式
老项目里最危险的 SQL 拼接,往往藏在 mysql_query(或 mysql_db_query)调用中,且参数直接来自 $_GET、$_POST 或未过滤的变量。比如:
$id = $_GET['id'];<br>$sql = "SELECT * FROM users WHERE id = $id";<br>mysql_query($sql);这种写法没有引号包裹、无类型校验、无转义,
id=1 OR 1=1 就能直接拖库。实操建议:
• 用 IDE 全局搜索 mysql_query(、mysql_db_query(,再人工筛出含 $_、$ 变量插值的行
• 注意别漏掉拼接在中间的字段,例如 "WHERE name LIKE '%$kw%'" —— 单引号包裹 ≠ 安全,$kw 仍可闭合引号注入
• 优先标记“带用户输入+无函数包裹”的组合,这类风险最高
用 mysqli::prepare 替换时必须处理的三类参数
不是所有旧 SQL 都能直接套 prepare,常见卡点在参数类型和占位符位置:
• 数字型字段(如 id、status):必须用 i 类型绑定,不能传字符串;否则查不到数据或报错 mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters
• 字符串型字段(如 name、email):用 s,但注意 NULL 值需显式传参,不能留空
• IN 子句(如 WHERE id IN (1,2,3)):无法直接用单个 ?,得动态生成占位符串,再 str_repeat('?,', count($ids) - 1) . '?' 拼出来,再绑定数组
示例(安全替换):
$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ? AND status = ?");<br>$stmt->bind_param("ii", $id, $status); // 两个 i,不是 "is"<br>$stmt->execute();
兼容性兜底:没时间重写全部,先加 mysqli_real_escape_string 临时防护
如果项目还依赖 mysql_* 函数、又没法立刻升级到 mysqli 或 PDO,临时加固比裸奔强。但注意:mysqli_real_escape_string 不是万能的,只对单引号、双引号、反斜杠等做转义,且必须指定连接句柄,否则无效。
常见错误:
• 忘记先调用 mysqli_connect,导致 mysqli_real_escape_string() 返回 false 或警告
• 对数字字段也加引号+转义(如 "$id"),反而引发类型隐式转换,可能绕过部分校验
• 把转义后的字符串再拼进另一个 SQL —— 二次转义会破坏原意
正确姿势:
$conn = mysqli_connect($host, $user, $pass, $db);<br>$safe_name = mysqli_real_escape_string($conn, $_POST['name']);<br>$sql = "INSERT INTO users (name) VALUES ('$safe_name')"; // 字符串字段才加单引号
警惕 LIKE 和 ORDER BY 这类无法参数化的字段
预处理语句的 ? 占位符只能代入**值**,不能代入字段名、表名、排序方向(ASC/DESC)或 LIKE 的通配符位置。这类地方即使用了 prepare,仍需白名单校验。
例如:
• ORDER BY $_GET['sort'] → 必须限定为 ['id', 'name', 'created_at'] 中的一个
• WHERE name LIKE '%$kw%' → $kw 可以预处理,但 % 符号得拼在绑定值里:$stmt->bind_param("s", "%{$kw}%"),而不是写在 SQL 字符串里
• 表名动态切换(如分表)→ 只能靠硬编码白名单或配置映射,绝不可拼接
最容易被忽略的是 GROUP BY 和 HAVING 后的字段,它们和 ORDER BY 同属语法结构层,参数化无效,必须走校验逻辑。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











