PHP中WHERE条件必须用预处理参数绑定防SQL注入,禁用字符串拼接;动态条件需构建SQL与参数数组;LIKE应将%拼入变量;NULL判断须用IS NULL而非= NULL。

PHP 查询语句加 WHERE 条件,核心不是拼 SQL 字符串,而是用预处理防止 SQL 注入——直接拼接 $name 或 $_GET['id'] 是危险操作。
WHERE 条件必须用预处理(PDO 或 MySQLi)
手写 "SELECT * FROM user WHERE name = '$name'" 看似简单,但一旦 $name 是 ' OR 1=1 -- ,整张表就可能被拖走。真实项目里,所有带变量的 WHERE 都该走参数绑定。
- PDO 推荐写法:
$stmt = $pdo->prepare("SELECT * FROM user WHERE status = ? AND age > ?"); $stmt->execute([1, 18]); - MySQLi 面向对象写法:
$stmt = $mysqli->prepare("SELECT * FROM user WHERE id = ?"); $stmt->bind_param("i", $id); $stmt->execute(); - 注意
"i"(整型)、"s"(字符串)这些类型标识不能漏,否则bind_param会静默失败
多个 WHERE 条件怎么动态拼接
搜索页常要“有值才加条件”,比如用户只填了 category 没填 price_min。这时不能硬写死所有字段,得动态构建 SQL 和参数数组。
- 先定义基础 SQL:
$sql = "SELECT * FROM product WHERE 1=1"; $params = []; - 按需追加:
if (!empty($category)) { $sql .= " AND category = ?"; $params[] = $category; } - 执行前统一绑定:
$stmt = $pdo->prepare($sql); $stmt->execute($params); - 别用
WHERE 1=1就以为安全——后面所有?还是得对应$params的顺序和数量,错一个就报错或查不到数据
LIKE 模糊查询的坑:通配符位置和索引失效
WHERE name LIKE '%关键词%' 虽然能搜到,但 MySQL 无法用上 name 字段的普通 B-Tree 索引,大数据量时会全表扫描。
立即学习“PHP免费学习笔记(深入)”;
- 想走索引,尽量把
%放右边:WHERE name LIKE '张%'(前缀匹配) - 如果必须前后模糊,考虑全文索引(
FULLTEXT)或 Elasticsearch - 预处理中写
LIKE要把%拼进变量,不是 SQL 里:$keyword = "%{$keyword}%"; $stmt->execute([$keyword]); - 别写成
WHERE name LIKE ?%——?后面的%不会被当参数处理,语法错误
NULL 值判断不能用等号,要用 IS NULL
WHERE 条件里查字段是否为空,写 WHERE deleted_at = NULL 永远不成立,因为 NULL = NULL 返回的是 NULL(不是 true)。
- 正确写法只有两种:
WHERE deleted_at IS NULL或WHERE deleted_at IS NOT NULL - 如果这个字段也要支持变量传入(比如前端传
"null"字符串表示查空),得在 PHP 层判断:if ($input === 'null') { $sql .= " AND deleted_at IS NULL"; } - 别试图用
COALESCE(deleted_at, '0')去套等号——逻辑绕、性能差、还容易和真实数据冲突
WHERE 条件看着只是加几个字,但每种写法背后都连着安全性、可维护性和执行效率。最常被忽略的其实是参数类型绑定和 NULL 判断逻辑——这两个点出问题,轻则查不出数据,重则整个库被拖库。











