tp5.1强制where使用索引数组格式,关联数组仅支持纯值等值映射,嵌套表达式、exp需db::raw()包裹,空数组会中断查询链。

TP5.0 升级到 5.1 后,where 数组写法会静默失效或报错,核心原因是 5.1 强制改用索引数组格式,关联数组仅保留最简等值映射,且不再支持嵌套表达式。
TP5.1 不再接受 ['field' => ['like', '%val%']] 这种写法
TP5.0 允许在关联数组中直接写带操作符的子数组,比如:['name' => ['like', '%think%'], 'status' => 1]。但 TP5.1 开始,这种写法会被忽略——字段名作为 key 时,只认纯值(如 'name' => 'thinkphp'),其余全当无效键丢弃。
- 现象:查询返回空结果,不报错,调试时
getLastSql()显示 WHERE 条件缺失 - 原因:5.1 的解析逻辑跳过所有 value 是数组的关联项,只处理
string/int/bool类型值 - 正确替代写法必须用索引数组:
[['name', 'like', '%think%'], ['status', '=', 1]] - 注意:字符串中的逗号不能省略,
['id', 'in', '1,2,3']和['id', 'in', [1,2,3]]都合法,但后者更安全(避免字符串注入)
whereOr 和多维条件必须统一用索引数组
TP5.1 的 whereOr、whereNot 等扩展方法,只接受索引数组输入。若混用关联数组,会触发「Array to string conversion」警告或 SQL 语法错误。
- 错误示例:
->whereOr(['id' => ['>', 10], 'name' => ['like', '%php%']])→ 解析失败 - 正确写法:
->whereOr([['id', '>', 10], ['name', 'like', '%php%']]) - 复杂场景建议封装闭包:
->whereOr(function ($q) { $q->where('id', '>', 10)->where('name', 'like', '%php%'); }) - 如果条件动态拼接,务必用
$where[] = [...]追加,不要用$where['key'] = [...](5.1.8+ 已废弃该用法)
exp 表达式必须配合 Db::raw()
TP5.1.9 起,exp 操作符不再接受原始字符串,否则会把 SQL 片段当字面量拼进参数占位符,导致语法错误。
- 错误写法:
['score', 'exp', '>total_score']→ 生成WHERE score = '>total_score' - 正确写法:
['score', 'exp', Db::raw('>total_score')]→ 生成WHERE score > total_score - 同理,
Db::raw('COUNT(*) as cnt')用于字段别名时也必须显式包裹 - 漏掉
Db::raw()是升级后常见 500 错误源头,日志里通常显示「SQLSTATE[42000]」或「Unknown column」
真正容易被忽略的是:TP5.1 对空数组条件的容忍度极低。比如 where([]) 在 5.0 可能无影响,但在 5.1 会直接中断查询链,后续 order 或 limit 全部失效。动态组装条件时,务必先 if (!empty($where)) 再调用 where($where)。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











