<p>Laravel 9 升级至 11 必须经由 9→10→11 的逐版本路径,不可跳过 v10;需先确保 PHP ≥8.2,再同步更新 composer.json 中所有 laravel/* 包版本、运行 php artisan upgrade 迁移结构,并彻底验证缓存、配置与核心功能。</p>

从 Laravel 9 升级到 11 不是改个版本号就能跑通的事,中间隔着两个主版本的结构性重构、PHP 版本跃迁、目录树重排和大量静默失效的 API,跳过 v10 直接升 v11 会导致 artisan 命令无法启动、中间件注册失败、配置项被覆盖、甚至队列任务永久卡死。
确认起点与路径
先执行 php artisan --version 确认当前确实是 Laravel 9.x(如 9.52.15),不是 9.x 的某个 patch 版本误标为 10。Laravel 官方只维护相邻主版本升级路径,【9 → 10 → 11 是唯一合法路径】,任何试图用 composer update "laravel/framework:^11.0" 强行跨升的操作,都会在解析 illuminate/support 时触发版本撕裂,最终报错 Class 'Illuminate\Support\ServiceProvider' not found —— 这不是代码写错了,是 Composer 根本没装对依赖树。
再运行 php -v 查看 PHP 版本:Laravel 10 要求 ≥ 8.1,Laravel 11 要求 ≥ 8.2。若当前是 PHP 8.1,必须先升级 PHP 再动框架;若仍是 8.0 或更低,连 Laravel 10 都无法安装。
升级到 Laravel 10
第一步:修改 composer.json 中的约束条件。
将 "laravel/framework": "^9.0" 改为 "laravel/framework": "^10.0",同时更新 "php": "^8.1"(不能留空或沿用旧值);把 "nunomaduro/collision": "^6.1" 换成 "spatie/laravel-ignition": "^2.4";将 "laravel/sanctum": "^3.0" 升至 "^3.3";"laravel/tinker": "^2.8" 改为 "^2.9"。
第二步:锁定生态包,避免自动拉入不兼容版本。
在 composer.json 的 "require-dev" 下添加 "laravel/upgrade": "^1.0",然后运行:
composer require laravel/upgrade --dev
第三步:执行受控更新。
不要直接运行 composer update。执行:
composer update laravel/framework laravel/tinker spatie/laravel-ignition --with-all-dependencies
加 --with-all-dependencies 是关键——它强制 Composer 同步升级所有子依赖(如 illuminate/*、symfony/*),否则 illuminate/database 可能卡在 9.x,而 framework 已是 10.x,容器绑定直接断裂。
第四步:结构迁移。
运行:
php artisan laravel:upgrade
该命令会自动替换 bootstrap/app.php、重写 App\Providers\RouteServiceProvider、清理 config/app.php 中已废弃的 'providers' 手动数组声明,并把中间件组定义从 $middlewareGroups 移至新位置。这一步不可跳过,手动复制粘贴目录只会让 HTTP 内核无法识别路由。
升级到 Laravel 11
方法一:环境与依赖预检
确认 PHP 已升至 8.2+;运行 composer outdated "laravel/*",确保 laravel/sanctum 显示 ^4.0、laravel/pint ≥ 1.14、laravel/sail ≥ 1.27;检查 .env 中 APP_KEY 是否为 32 字符 base64 字符串,Laravel 11 默认启用强校验,旧格式 key 会导致 session 解密失败、登录态丢失。
方法二:composer.json 全量更新
将 "laravel/framework": "^10.0" 改为 "laravel/framework": "^11.0";"php": "^8.2";"spatie/laravel-ignition": "^2.8";"laravel/sanctum": "^4.0";"laravel/tinker": "^2.10";删掉所有显式声明的 "illuminate/*" 包——Laravel 11 不再允许手动管理子包版本,它们由 framework 自动约束。
方法三:执行最终迁移
第一步:清缓存并卸载旧扩展
php artisan config:clear && php artisan cache:clear
composer remove laravel/upgrade --dev
第二步:安装新版升级助手
composer require laravel/upgrade --dev
第三步:运行骨架重写
php artisan upgrade
这个命令会删除 app/Http/Controllers、app/Http/Middleware、app/Console/Commands 等目录(Laravel 11 默认不生成),新建 app/Support、app/Actions,并重写 Kernel.php 为轻量结构。它还会检测并移除 config/app.php 中重复注册的 ServiceProvider,避免 Provider already registered 错误。
第四步:验证结构完整性
检查 database/migrations/ 目录下是否仍有带时间戳的迁移文件,若有,请确保它们全部通过 php artisan migrate 执行完毕;运行 php artisan db:seed 若项目使用了种子器,注意 Laravel 11 的 Seeder 类签名已改为 public function __invoke(): void,旧写法会报错。


















