ThinkPHP6升级需重构命名空间、路由、中间件、数据库查询及模板机制。命名空间移至think\facade*和think\contract*;路由须集中于app/route.php并返回RuleGroup;中间件分应用级、路由级、控制器级;Db默认严格字段检查需生成schema缓存;URL生成需配置白名单或使用命名路由。

ThinkPHP5升级到ThinkPHP6不是简单替换版本号,而是框架底层结构的重构。很多问题在安装时没报错,运行后才陆续暴露——核心在于命名空间、自动加载、路由机制、中间件注册和数据库查询逻辑这五处发生了根本性变化。
命名空间与类引用全部重排
TP5中\think\Route、\think\Db等类直接位于think\*根命名空间下;TP6则统一迁移至think\facade\*(门面)和think\contract\*(契约)。如果你沿用TP5写法:
– use think\Route; → 会报Class 'think\Route' not found
– Route::get()在控制器里调用 → 报Call to undefined method think\Route::get()
正确做法是:
– 改用门面: use think\facade\Route;
– 路由定义必须写在app/route.php中,且该文件需返回RuleGroup实例
– 模型类不再继承\think\Model,而是\think\Model(仍存在但语义不同),推荐使用\think\Model并配合protected $schema = []显式声明字段
路由注册方式彻底改变
TP5支持全局函数式路由(如Route::get('index', 'index/index')),TP6已完全移除该能力,所有路由必须集中注册在app/route.php中,并通过return Route::group(...)返回规则组。
立即学习“PHP免费学习笔记(深入)”;
常见踩坑点:
– 把路由写在控制器或中间件里 → 直接报错或静默失效
– 多应用模式下,误将app/api/route.php当成全局路由入口 → 需确认应用初始化时是否加载了该文件
– 使用route/目录(TP5习惯)→ TP6不识别,必须放在app/下
中间件配置逻辑重构
TP5通过app/middleware.php数组全局注册,TP6废弃此方式,改为:
– 应用级中间件:仍在app/middleware.php中返回类名数组,如return [App\Middleware\CheckAuth::class];
– 路由级中间件:必须显式链式调用->middleware(CheckAuth::class)
– 控制器级中间件:需在控制器构造方法或initialize()中调用$this->middleware(...)
注意:
– 全局中间件不会自动注入到所有路由,只对未显式指定中间件的路由生效
– 中间件执行顺序为:全局 → 路由组 → 单条路由,同级多个按数组顺序执行,无隐式优先级
Db查询返回null或字段映射异常
TP6默认开启严格字段检查,首次部署若未生成字段缓存,Db::table('user')->where('id', 1)->find()可能返回null,即使数据真实存在。
验证与修复:
– 加->strict(false)临时测试,能查出说明是字段缓存问题
– 立即运行php think optimize:schema生成缓存
– 更可靠方案:为表创建模型类,并在其中设置protected $schema = ['id' => 'int', 'name' => 'string'],绕过自动探测
– 若用原生SQL或query(),不受此限制,但失去字段类型转换优势
模板函数与URL生成失效
TP5中{:url('index/index')}在TP6中可能渲染为空或报错,原因有二:
– URL生成函数未加入function白名单(config/template.php中'function' => ['url' => '\think\Url::build'])
– 更推荐使用命名路由:Route::get('home', 'index/index')->name('home');,模板中改用{:url('home')}
其他模板兼容点:
– {:widget('xxx')}被移除,需改用{:include('widget/xxx')}或自定义标签
– {:volist}语法保留,但empty属性行为微调,建议显式加{:empty}暂无数据{:\/empty}



















