tp6.0查询构造器与tp5.1不兼容:where数组仅支持字段=值简写,select返回collection对象需toarray()转数组,findorfail抛validateexception而非dbexception。

TP6.0 查询数据不能直接套用 TP5.1 的写法,多数老代码迁过来会查不到结果或报错,核心差异在 where 结构、select 返回值类型和异常机制。
where 条件写法不兼容:数组传参只认「字段=值」
TP6.0 的 where(['status' => 1, 'type' => 'user']) 会被当作两个 = 条件拼接,但不支持嵌套或混合操作符。一旦你写 where(['id' => ['in', [1,2,3]], 'status' => 1]),它不会解析 ['in', [...]],而是直接当字符串赋值,最终 SQL 变成 WHERE `id` = 'Array' AND `status` = 1 —— 明显查不到数据。
- 正确写法是链式调用:
where('id', 'in', [1,2,3])->where('status', 1) - 复杂逻辑用闭包分组:
where(function ($query) { $query->where('id', 'in', [1,2,3])->whereOr('name', 'like', '%admin%'); }) - 批量条件用二维数组:
where([['name', 'like', '%a%'], ['status', '=', 1], ['score', '>=', 60]]),注意每个子数组必须是三元组 - 用户输入参与构造时,务必把变量单独拎出来,别让整个数组受控:
where([['name', 'like', $keyword . '%'], ['status', '=', $status]])
select() 返回的是 Collection,不是数组
执行 User::where('status', 1)->select() 后,$list 是 think\Collection 对象,不是 PHP 关联数组。所以 $list[0]['name'] 会报错,json_encode($list) 虽然能工作,但若模型重写了 toJson() 或设置了 $hidden,可能漏字段。
- 需要原生数组就加
->toArray():User::where('status', 1)->select()->toArray() - 遍历仍可用
foreach ($list as $item),Collection 实现了Iterator - API 输出前建议统一做
->toArray(),避免隐式序列化行为不一致 - 调试时想看 SQL,别 print_r 对象,改用
buildSql():User::where('status', 1)->buildSql()
findOrFail 抛的是 ValidateException,不是 DbException
TP6.0 中 findOrFail() 找不到记录时抛出 think\exception\ValidateException,且默认附带 HTTP 404 响应头。如果你还在 catch (DbException $e) 里兜底,这个异常根本捕获不到,直接透出到框架顶层,前端收到 500 或 404 却没走你的错误处理逻辑。
- 升级后必须改捕获类型:
catch (\think\exception\ValidateException $e) - 若需保持原有 DbException 行为,可手动判断:
$data = User::find($id); if (!$data) throw new DbException('not found'); - 注意
findOrEmpty()和selectOrFail()这类方法也遵循同样异常规则 - API 场景下,别依赖异常类型做业务分流,优先用
if (!$data) return fail('xxx');
动态条件要用 when,但闭包必须 return 查询对象
when() 是 TP6 推荐的动态条件写法,但它不像 Laravel 那样自动返回查询实例。闭包内部所有链式调用都得显式 return $query,否则条件被丢弃,SQL 里完全看不到对应 WHERE 子句。
- 错误示范:
->when($uid, function ($q) use ($uid) { $q->where('uid', $uid); })—— 缺少return - 正确写法:
->when($uid, function ($q) use ($uid) { return $q->where('uid', $uid); }) - 多个
when嵌套时,顺序即 SQL 中条件顺序;如需 OR 分组,不能靠when堆叠,得用whereOr(function () {...}) - 判真逻辑要严谨:
$uid === null和empty($uid)效果不同,when(0, ...)默认不触发,但业务上 0 可能是合法 ID,建议用when(!is_null($uid), ...)
TP6.0 查询构造器表面只是语法微调,实际影响的是条件组装逻辑、返回结构语义和异常控制流——最容易被忽略的是 where 数组降级为纯等值映射,以及 Collection 对象在数组访问上的“假兼容”。上线前务必检查所有 select() 后的索引访问和异常捕获块。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











