yii2中where查询最安全推荐用数组形式,自动转义防注入;范围查询用字符串+参数绑定;动态条件用andwhere/orwhere分段构建;查不到数据时需验证输入值和生成sql。

Yii2 中 where 查询最常用写法
直接用数组形式是最安全、最推荐的入门方式,自动转义防止 SQL 注入。适用于等值查询、IN、NULL 判断等常见场景。
示例:查状态为 1 且类型在指定列表中的用户
$users = User::find()
->where([
'status' => 1,
'type' => [1, 2, 3],
'deleted_at' => null
])
->all();
-
status => 1生成status = 1 -
type => [1, 2, 3]自动变成type IN (1, 2, 3) -
deleted_at => null会生成deleted_at IS NULL,不是= NULL
需要范围查询或运算符时用字符串 + 参数绑定
当要写 >、BETWEEN、LIKE 或混合逻辑时,数组不够用,必须改用字符串形式并配合参数占位符,避免拼接导致的注入风险。
示例:查创建时间在某区间、用户名含关键词的用户
$users = User::find()
->where('created_at >= :start AND created_at '2024-01-01',
':end' => '2024-12-31',
':keyword' => '%admin%'
])
->all();
- 占位符必须以冒号开头(如
:start),不能用?问号占位(那是 PDO 原生写法,Yii 不认) -
LIKE的通配符(%)要写在参数值里,不要塞进 SQL 字符串 - 字符串中不能出现 PHP 变量插值,否则失去参数绑定保护
复杂条件组合用 andWhere / orWhere 分段构建
动态加条件(比如搜索表单有可选字段)时,硬塞进一个 where() 容易出错;用链式方法更清晰、不易漏括号。
示例:根据传参动态添加条件
$query = User::find();
if (!empty($params['status'])) {
$query->andWhere(['status' => $params['status']]);
}
if (!empty($params['keyword'])) {
$query->andWhere(['like', 'username', $params['keyword']]);
}
if (!empty($params['min_age'])) {
$query->andWhere(['>=', 'age', $params['min_age']]);
}
$users = $query->all();
-
['like', 'username', $keyword]是 Yii 特殊语法,自动加%并转义,比手写LIKE更省心 -
andWhere默认加AND,orWhere加OR;多个orWhere连用时注意优先级,必要时用['or', [...], [...]]显式分组 - 别在循环里反复调用
where(),它会覆盖前面的条件;必须用andWhere累加
查不到数据?先确认 where 是否真生效了
常见静默失败原因不是语法错,而是条件值本身有问题:空字符串、0、false 被当成有效过滤值,或者时间/日期格式不匹配数据库存储格式。
- 对字段做
var_dump($model->attributes)看实际取到的值,别只信前端传参 - 用
createCommand()->getRawSql()打印最终 SQL,例如:echo User::find()->where(['id' => 1])->createCommand()->getRawSql(); - MySQL 中
DATETIME字段查'2024-01-01'可能不命中,因为默认是'2024-01-01 00:00:00',建议用BETWEEN或函数处理
条件越动态,越要验证每一步的输入和生成的 SQL,而不是假设框架“应该懂”。











