tp5的where数组条件在tp8中不再兼容,因底层查询构造器彻底重构;tp8仅支持三元组、闭包或简单键值对,需改用链式调用如where('id','in',[1,2,3])或闭包封装。

TP5 升级到 TP8 后,where 数组条件写法**不再兼容**,直接沿用 TP5 的数组结构会查不到数据或报错——这不是语法糖差异,而是查询构造器底层彻底重构了。
TP5 的 where(['id' => ['in', [1,2,3]], 'status' => 1]) 在 TP8 中无效
TP8 已移除对混合操作符数组的解析能力。原 TP5 支持的关联数组中嵌套 ['in', [...]]、['like', '%val%'] 等写法,在 TP8 中会被当作字段名字符串处理,最终生成错误 SQL(如 WHERE `id` = "Array")。
- 常见错误现象:
where(['name' => ['like', '%admin%']])查询返回空,日志里看到的是WHERE `name` = 'Array' - 根本原因:TP8 的
where()方法只接受「字段-操作符-值」三元组、闭包,或最简键值对(自动转为=) - 正确迁移方式不是“改写数组”,而是改用链式调用或闭包
TP8 替代写法:链式调用 or 闭包 where
必须显式声明操作符,不能依赖数组结构隐含语义。以下两种写法在 TP8 中等效且推荐:
- 链式调用(清晰、易调试):
Db::table('user')->where('id', 'in', [1,2,3])->where('status', '=', 1)->select() - 闭包封装(适合复杂条件组合):
Db::table('user')->where(function ($query) { $query->where('id', 'in', [1,2,3])->whereOr('name', 'like', '%admin%'); })->select() - 注意:
whereOr和whereNot等方法在 TP8 中需明确作用于闭包内,不能靠数组末尾加'or'字符串
FIND_IN_SET 这类 MySQL 函数要改用 exp + raw
TP5 中常见的 $map[] = ['exp', 'FIND_IN_SET(2,category)'] 写法,在 TP8 中仍可用,但必须配合 Db::raw() 防止被自动转义:
- 错误写法:
where('FIND_IN_SET(2,category)')→ TP8 会把它当字段名处理 - 正确写法:
where('FIND_IN_SET(:id,category)', ['id' => 2])或where(['exp', Db::raw("FIND_IN_SET(2,category)")]) - 带变量时务必用参数绑定:
where('FIND_IN_SET(:id,category)', ['id' => $adminId]),避免 SQL 注入
升级后最容易忽略的点是:TP8 不再尝试“猜”你的意图。它不会把 ['name' => ['like', '%x%']] 拆解成 LIKE 条件,也不会把二维数组自动识别为 OR 组合。所有逻辑必须由你显式写出——这不是倒退,而是把控制权交还给开发者,避免隐式行为引发的线上故障。











