thinkphp6是架构重写的产物,非tp5简单升级;其app/目录为单应用根(小写、psr-4严格对齐),取代tp5的多模块application/(大写、自动识别模块),多应用需额外安装think-multi-app并手动绑定,不支持路径自动切换。

ThinkPHP6 不是 ThinkPHP5 的简单升级版,而是架构重写后的产物;如果你项目里大量用 new \app\service\UserService()、硬编码 Db::name()、依赖 application/ 目录结构或直接调用 think\Controller,那基本没法平滑迁移到 TP6。
TP6 的 app/ 目录和 TP5 的 application/ 完全不是一回事
TP5 的 application/ 是多模块起点,目录名首字母大写,自带 index/、admin/ 等子目录,路由靠模块名自动识别;TP6 的 app/(小写)是单应用默认根,没有预置模块,所有类路径必须严格对齐 PSR-4:比如 app\controller\Index 必须对应 app/controller/Index.php。
若需多应用(如 admin.xxx.com 对应独立配置),必须手动执行:composer require topthink/think-multi-app
然后在 app/multi_app.php 里注册,再通过子域名或入口文件绑定,不能靠 URL 路径自动切换。
- TP5 中
application/common.php是全局加载的;TP6 中各应用的公共函数得放在app/admin/common.php并在app/admin/provider.php里显式引入 - TP5 模块间共享
config.php,常靠if (MODULE_NAME === 'admin')分支控制;TP6 每个应用可拥有独立的app/admin/config/database.php - 新增控制器后不执行
composer dump-autoload -o,会直接报Class not found
模板引擎从“默认开”变成“默认关”,且语法不兼容
TP6 默认使用原生 PHP 模板('type' => 'php'),不再内置 ThinkTemplate 引擎;要继续用 {volist}、{:func()} 这类语法,必须先装包:composer require topthink/think-template
并在 config/view.php 中设 'type' => 'think'。
关键差异点:
-
View::fetch()在 TP6 中不是静态方法,需确保topthink/think-view已安装,否则报Call to undefined method think\View::fetch() - 继承写法从
{extend name="public:base"}(TP5)变成{extend name="public@base"}(TP6),且public必须是已注册的独立应用 -
view_cache => false在 TP6.3+ 彻底失效,模板编译缓存强制开启;开发中改了模板没反应?只能清runtime/html/,不能关缓存
配置体系拆得更细,但 .env 不是万能覆盖层
TP6 把 TP5 的 config.php 拆成 config/app.php、config/database.php、config/route.php 等多个文件,结构清晰,但迁移时容易漏配。
.env 文件只负责覆盖那些显式调用 Env::get('DB_HOST') 或 env('DB_HOST') 的地方;如果 config/database.php 里还写着 'hostname' => '127.0.0.1'(硬编码),改 .env 就完全无效。
-
.env必须叫这个名字,.env.production或.env.local都不生效 -
view.replace在 TP5 是配置项,在 TP6 已挪到config/view.php的'replace' => ['__STATIC__' => '/static'],漏写双下划线前缀就白配 - TP6 默认不启用 session,验证码、登录态等依赖 session 的功能,需手动在
config/middleware.php中加入\think\middleware\SessionInit::class
依赖注入和容器行为变化最隐蔽也最致命
TP5 中控制器方法参数靠约定(如 public function index($id))或门面静态调用;TP6 默认启用类型提示自动解析,public function index(UserService $service) 会从容器取实例——但前提是该类已绑定或可自动实例化。
常见静默失败场景:
- 控制器构造函数里写了
new \app\service\UserService()→ TP6 不报错,但后续无法被测试或替换,且破坏 DI 原则 - 自定义服务没走
Container::set()或服务提供者register(),直接app('myservice')会返回 null - TP5 的
App::bind()全局单例绑定,在 TP6 中必须改为Container::set('myservice', new MyService())或在provider.php中声明
真正卡住人的地方往往不在文档写的“新特性”,而在那些没报错却逻辑错位的行为:比如路由匹配失败只返回 404(控制器方法名用了下划线 user_list,TP6 要求小驼峰 userList),或者异常堆栈被默认关闭(show_error_msg 需手动开),导致本地开发时你以为没出错,其实是静默吞掉了关键异常。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











