ThinkPHP 5.1 迁移至 6.0 模型查询报错主因是底层行为变更:where写法需改用链式或闭包、select返回Collection需toArray()、findOrFail抛ValidateException而非DbException、模型表名不再自动推导须显式指定。

ThinkPHP 5.1 迁移到 6.0 后模型查询报错,核心原因不是语法写错了,而是框架底层行为变了——where 结构、返回类型、异常机制、表名推导这四点不兼容,直接套用旧代码必报错或查不到数据。
where 条件写法必须重写
TP5.1 支持嵌套数组写法,比如:
where(['id' => ['in', [1,2,3]], 'status' => 1])
TP6.0 会静默失效或抛错,它只认链式调用或闭包封装。
- 简单等值条件可保留数组形式:
where(['name' => 'thinkphp'])→ 等价于where('name', '=', 'thinkphp') - 含操作符的必须拆开:
where('id', 'in', [1,2,3])->where('status', 1) - 复杂逻辑统一用闭包:
where(function ($query) { $query->where('id', 'in', [1,2,3])->where('status', '=', 1); }) - 用户输入的条件建议用
when(),避免空值导致整个条件被跳过
select() 返回的是 Collection,不是数组
TP5.1 的 select() 返回二维数组,可直接 $list[0]['name'];TP6.0 返回 think\Collection 对象,不能用下标访问。
- 要转成原生数组,必须显式加
->toArray():User::where('status', 1)->select()->toArray() - 遍历仍可用
foreach ($list as $item) { echo $item->name; }(注意是对象属性) - 只取单个字段值,优先用
value('name')或column('name'),比select()->toArray()更轻量
findOrFail 抛的是 ValidateException,不是 DbException
TP5.1 找不到记录时 findOrFail() 抛 DbException;TP6.0 改抛 ValidateException,且默认带 HTTP 404 响应头。
立即学习“PHP免费学习笔记(深入)”;
- 旧代码里
catch (DbException $e)完全捕获不到这个异常,必须改成catch (ValidateException $e) - 如果在命令行或后台任务中不想触发 HTTP 响应,建议手动判断:
$user = User::find($id); if (!$user) throw new HttpException(404); -
findOrEmpty()和selectOrFail()行为一致,也都抛ValidateException
模型表名不再自动推导
TP5.1 模型类名(如 User)默认映射表名 user;TP6.3+ 已默认禁用该行为,未显式声明表名会报错或查空。
- 在模型类中加
protected $table = 'user';显式指定 - 或者用
protected $name = 'user';(兼容老习惯) - 若用 Db 类直查,
Db::name('user')已废弃,必须改用Db::table('user')



















