信息发布→ 登录 注册 退出

如何将一个旧的Laravel项目平滑升级到最新版本? (升级指南与步骤)

发布时间:2026-01-14

点击量:
必须逐个主版本升级Laravel,跳过中间版本会导致依赖冲突、API失效等异常;需匹配PHP版本、备份配置、通过测试、锁定第三方包,并使用官方升级助手及手动修正变更。

不能直接跨大版本升级,必须逐个主版本迭代,否则 composer update 会失败或引发大量运行时异常。

确认当前版本与目标版本的兼容路径

Laravel 的主版本升级(如 8 → 9 → 10 → 11)不是线性平滑的,每个版本都有明确的 PHP 版本、依赖包和废弃 API 要求。跳过中间版本大概率导致 illuminate/support 冲突、Facade 类找不到、或 Route::middleware() 行为变更等隐性问题。

  • 查当前版本:
    php artisan --version
    或看 composer.json"laravel/framework" 的约束值(如 "^8.75"
  • 查升级路径:官方只维护相邻主版本的升级指南,例如 Laravel 10 升级文档只覆盖从 9 升到 10,不支持从 8 直升 10
  • PHP 版本必须匹配:Laravel 11 要求 PHP ≥ 8.2,若当前是 PHP 8.0,需先升级 PHP 再动框架

每次升级前必须做的三件事

这不是可选步骤,漏掉任意一项都可能让升级后应用在 CI 或生产环境凌晨三点崩溃。

  • 备份整个 composer.lock 文件和 config/ 目录 —— 尤其是 config/app.php 和自定义配置项,升级脚本常静默覆盖它们
  • 确保全部测试通过:
    vendor/bin/phpunit
    ,重点盯住 Feature 测试里涉及表单验证、中间件顺序、队列 job 序列化的用例
  • 禁用所有第三方包的自动更新:在 composer.json 中临时锁定关键包,例如 "spatie/laravel-permission": "^5.10"(对应 Laravel 9),避免 composer update 同时拉入不兼容新版 Laravel 的包

执行升级的核心命令与关键检查点

以 Laravel 9 → 10 为例(其他主版本同理),核心动作是替换骨架文件 + 修正迁移层变更,而非仅改 composer 版本号。

  • 修改 composer.json"laravel/framework""^10.0",同时更新 "php" 约束(如 "^8.1"
  • 运行:
    composer update "laravel/framework" "laravel/tinker" --with-all-dependencies
    ,加 --with-all-dependencies 是防止 illuminate/* 子包版本撕裂
  • 运行官方升级助手:
    php artisan laravel:upgrade
    (需先 composer require laravel/upgrade --dev),它会自动替换 app/Providers/RouteServiceProvider.php、修复 bootstrap/app.php 结构等
  • 手动检查:是否还存在 use Illuminate\Support\Facades\Hash; 这类被移到 Illuminate\Hashing\HashManager 的引用;config/cache.php 中的 stores.file 是否被移除(Laravel 10+ 不再支持 file 缓存驱动)

升级后高频报错与速查方案

这些错误不会出现在升级文档首页,但几乎每个项目都会撞上:

  • Target class [App\Http\Controllers\Controller] does not exist:Laravel 9+ 移除了默认的基类控制器,需把所有控制器继承改为 extends Illuminate\Routing\Controller 或删掉 extends Controller
  • Call to undefined method Illuminate\Database\Query\Builder::whenLoaded():这是 Eloquent 的 lazy eager loading 方法,Laravel 10 改名为 whenHas(),全局搜索替换即可
  • Class 'App\Providers\AppServiceProvider' not found:升级助手有时漏改 bootstrap/app.php 中的命名空间引用,确认是否还是 App\Providers\AppServiceProvider::class(Laravel 10+ 默认去掉 App\ 前缀)
  • 队列 job 执行失败且无日志:检查 app/Jobs/YourJob.php 是否仍用 implements ShouldQueue 但没加 use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; trait —— Laravel 9+ 强制要求显式 use

最麻烦的从来不是命令行那几行输出,而是 config 文件里某个被注释掉的旧配置,在升级后意外生效,或者某张 migration 表用了 $table->jsonb()(PostgreSQL only),而新版本默认 MySQL 驱动根本不认识这个方法 —— 动手前,先通读目标版本的「Breaking Changes」列表,比跑十遍 composer update 更省时间。

标签:# class  # 用了  # 出现在  # 找不到  # 尤其是  # 都有  # 文档  # 这是  # 移除  # 跳过  # 第三方  # http  # postgresql  # database  # table  # undefined  # mysql  # 继承  # require  # 表单验证  # 命名空间  # 中间件  # ai  # app  # cad  # composer  # json  # bootstrap  # js  # laravel  # php  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!