查不到记录时需先确认是否调用one()或all()执行查询:find()仅返回activequery对象,未执行sql;one()返回null(须用=== null判断),all()返回空数组;主键不匹配、作用域过滤、软删除及连接库错误亦常见。

查不到记录时先确认 find() 是否加了 one() 或 all()
Yii 的 ActiveRecord 查询默认返回的是 ActiveQuery 对象,不是实际数据。直接打印或判断结果为空,往往是因为忘了执行查询动作。常见错误写法:User::find()->where(['id' => 123]) —— 这只是构建查询,没真正执行。
- 要取单条记录,必须链式调用
one();要取多条,用all() - 如果 ID 不存在,
one()返回null,不是空数组或 false,用=== null判断更安全 - 调试时可临时加
createCommand()->getRawSql()看生成的 SQL 是否符合预期
检查主键字段名和表结构是否匹配 primaryKey()
Yii 默认假设主键是 id,但如果你的表主键是 user_id、uid 或复合主键,findByPk(123) 或 findOne(123) 就会查不到,甚至静默失败。
- 在模型中显式定义:
public static function primaryKey() { return ['user_id']; } - 用
var_dump(static::getTableSchema()->primaryKey)确认框架识别出的主键名 - 注意大小写:MySQL 默认不区分,但 PostgreSQL 或开启严格模式时,
UserID和user_id不等价
数据库连接、软删除和作用域(scope)干扰真实查询结果
查不到可能根本不是 SQL 问题,而是被中间层过滤掉了。Yii 的 softDelete 行为、全局 defaultScope、或当前连接指向了测试库,都会导致“有数据却查不到”。
- 临时禁用作用域:
User::find()->withoutGlobalScopes()->where(['id' => 123])->one() - 检查是否启用了
SoftDeleteBehavior,并确认deleted_at字段值是否为 NULL(非软删状态) - 用
Yii::$app->db->dsn打印当前连接的数据库名,排除连错库(比如连了test_db却往prod_db插入)
使用 findOne() 时传参类型不匹配引发隐式转换失败
MySQL 在 WHERE id = '123abc' 这种字符串对比整型主键时会转成 0,而 Yii 有时会把路由参数或表单输入原样传入,导致查 id = 0 —— 这个 ID 往往不存在。
- 强制类型转换:
User::findOne((int) $id)或User::findOne(['id' => (int) $id]) - 检查来源:URL 参数、POST 数据、Redis 缓存反序列化后是否带了空格或不可见字符(可用
trim()+is_numeric()验证) - 开启 MySQL 的
sql_mode=STRICT_TRANS_TABLES可让这类隐式转换报错,便于早期暴露问题
primaryKey() 和 behaviors()。











