ThinkPHP5 升级到 6.0 主要破坏性更新有哪些?

文章导读
ThinkPHP 6.0 是底层重构的全新框架,不兼容 ThinkPHP 5,无法通过 composer update 直接升级,必须新建项目迁移代码。核心破坏性更新包括目录结构变更、配置方式改为.env 优先、路由参数默认不合并、数据库查询返回 Collection 对象以及强制 PHP 7.1+ 环境。
📋 目录
  1. 快速处理思路
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

ThinkPHP 6.0 是底层重构的全新框架,不兼容 ThinkPHP 5,无法通过 composer update 直接升级,必须新建项目迁移代码。核心破坏性更新包括目录结构变更、配置方式改为.env 优先、路由参数默认不合并、数据库查询返回 Collection 对象以及强制 PHP 7.1+ 环境。

先说结论:TP6 不是 TP5 的补丁升级,而是架构重写,原地升级必报错。

  • 适合:需要 PHP 7.1+ 环境且愿意重构代码的项目
  • 重点看:配置从 config.php 拆分至模块化文件且.env 优先级最高
  • 别忽略:Db 查询返回 Collection 对象需转数组,路由参数需显式开启 merge_param

快速处理思路

升级前需确认环境满足 PHP 7.1+ 及 mbstring、json、openssl、fileinfo 扩展,执行 composer create-project 新建骨架后迁移逻辑。

php -m | grep -E "mbstring|json|openssl|fileinfo"
composer create-project topthink/think tp6

迁移时将旧 application/ 目录代码按 PSR-4 规范移入 app/,配置拆分为 config/ 下模块化文件,数据库密码含特殊字符需用双引号包裹。

为什么会这样

ThinkPHP 6.0 强制采用多项 PSR 规范,不再是可选兼容,导致核心类结构和命名空间彻底变更。框架从“单例 + 静态代理”转向标准 PSR-11 容器实现,bind() 只在当前容器实例内有效,不再影响全局容器。目录结构扁平化,config/ 目录不再支持子目录写法,数据库配置中 type 必须小写。这些架构理念变化使得旧代码无法直接运行,必须按新规范重构。

分步处理

第一步检查环境,确认 PHP 版本≥7.1.0 且启用必要扩展,Windows 用户需在 php.ini 手动开启 extension=php_fileinfo.dll。第二步新建 TP6 项目,执行 composer create-project topthink/think tp6,不要原地覆盖。第三步迁移代码,将旧控制器、模型移到 app/ 下并修正命名空间如 app\controller\Index。第四步重构配置,删除 config.php,改用 config/app.php 及.env 文件,确保.env 文件名无后缀。第五步调整路由,显式开启 merge_param 选项或改用资源路由。第六步修正数据库调用,Db::select() 返回 Collection 对象需调用->toArray()。第七步安装扩展,手动 composer require topthink/think-view 及 topthink/think-multi-app。

怎么验证是否生效

访问一个绝对不存在的路径,若返回 ThinkPHP 自带 404 页面说明请求已进框架,若返回 Nginx 默认 404 说明伪静态未生效。在 public/index.php 顶部加 var_dump($_SERVER['PATH_INFO']) 访问/index/index,输出应为/index/index。检查数据库查询结果类型,确认是否为对象而非数组,必要时加->toArray()。查看/www/wwwlogs/yourdomain_error.log 确认无 rewrite 相关报错。

ThinkPHP5 升级到 6.0 主要破坏性更新有哪些?

常见坑

配置文件结构全变,TP5 的 config.php 单文件模式在 TP6 里彻底废弃,老项目直接复制会静默失效。.env 文件名必须是纯.env 无后缀,数据库密码含@、#等特殊字符时必须用双引号包裹。控制器基类不再是 think\Controller,而是 think\controller\Base,继承错误会报错。模板引擎默认不加载,需手动安装 think-view 扩展,否则 fetch() 报错。容器绑定作用域受限,app() 和 think\Container::getInstance() 不再等价,混用会导致绑定失效。

常见问题

直接 composer update 能升级到 TP6 吗?

不能,TP6 是彻底重写的框架,composer update 默认只会拉取同主版本号更新,必须新建项目迁移。

为什么配置修改后不生效?

因为.env 环境文件优先级最高,若没建.env 或里面写了 APP_DEBUG=false,即使 PHP 里设了 app_debug = true 也无效。

路由参数$id 为什么拿不到值?

TP6 默认不自动合并 route 变量,需在路由定义显式开启 merge_param 选项或改用资源路由。

Db::name('user')->select() 返回什么类型?

返回 Collection 对象不再是数组,如需数组请调用->toArray(),不能直接 json_encode()。

参考来源

  • ThinkPHP5 升级到 ThinkPHP6 避坑指南_核心架构变更差异解析
  • ThinkPHP 从 5.1 升级到 6.0 的依赖注入变更与代码重构指南
  • ThinkPHP6.x 框架对比:从 ThinkPHP5 到 6.x 版本升级的核心差异与迁移指南
  • ThinkPHP5 升级到 ThinkPHP6 有哪些不兼容的地方_版本升级避坑【汇总】
  • 如何升级旧版 ThinkPHP 到 ThinkPHP6_底层架构变更与升级排错指南
  • ThinkPHP5 和 6 版本差异在哪里_ThinkPHP5 与 6 版本差异汇总【指南】
  • ThinkPHP5.1 升级 6.0 后伪静态失效修复全攻略【指南】
  • ThinkPHP5 转 6 要注意什么_ThinkPHP 版本迁移避坑汇总【技巧】
  • ThinkPHP 6.0 深度迁移实战:从架构革新到性能跃迁的完整路径
  • ThinkPHP6.0 与 5.0 的差别及坑点