必须逐个主版本升级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 更省时间。










