Laravel升级需严格按主版本顺序进行,先确认当前与目标版本、PHP兼容性,再同步更新全部依赖及结构,最后彻底清理缓存并排查废弃函数调用。

确认当前版本和目标版本再动手
直接改 composer.json 是最危险的起点。你得先知道现在跑的是啥、想升到哪——Laravel 不允许跨主版本跳升,比如从 9.x 直接升 11.x,中间 10.x 必须过一遍。php artisan --version 能快速看当前版本;查 composer.json 里 "laravel/framework" 的值更准,尤其当 Artisan 命令本身已因升级中断时。
- PHP 版本必须匹配:Laravel 11 要求
^8.2,低于就先升 PHP,否则composer update会静默失败或装错依赖 - 别信“最新版”这种模糊说法——截至 2026 年 3 月,
^11.0是当前稳定主版本,但你的项目可能卡在 8.x,那就要规划 8→9→10→11 三步走 - 用
composer outdated "laravel/*"快速扫一遍第一方包是否滞后,比如laravel/sanctum在 11.x 下必须是^4.0,旧版会报Class not found
改 composer.json 不能只动 framework 一行
只把 "laravel/framework": "^10.0" 改成 "^11.0" 是常见翻车点。Laravel 主版本升级会连带更新整套依赖树,包括错误处理器、测试工具、HTTP 客户端等,漏掉任何一个都可能导致 artisan 启动失败或测试崩掉。
- 同步更新关键配套包:
"spatie/laravel-ignition": "^2.4"(代替旧版facade/ignition)"nunomaduro/collision": "^8.1""phpunit/phpunit": "^10.5"(注意不是^11.0,11.x 尚未被 Laravel 11 官方支持) -
"php"字段必须显式声明:如"php": "^8.2",否则 Composer 可能沿用旧约束,导致安装降级版依赖 - 加
--with-all-dependencies参数运行:composer update --with-all-dependencies,避免部分包被锁在旧版本不动
结构迁移比代码修改更易被忽略
Laravel 11 引入了「轻量应用结构」,默认不生成 app/Http/Controllers、app/Http/Middleware 等目录,而是靠 php artisan upgrade 自动补全。很多人手动创建目录、复制文件,结果 AppServiceProvider 里的 register() 方法签名没变但容器绑定逻辑已重构,导致服务解析失败。
- 先装升级助手:
composer require laravel/upgrade --dev - 再执行迁移:
php artisan upgrade(它会重写app/Providers/HttpKernel.php、调整中间件组定义、清理废弃的$middlewareGroups键) - 检查
config/app.php是否还残留'providers' => [App\Providers\AppServiceProvider::class]这种写法——Laravel 11 推荐用命名空间全路径,且部分服务提供者已被自动注册,重复声明会报Provider already registered
缓存清不干净,升级等于白干
升级后访问首页 500,控制台没报错,storage/logs/laravel.log 里只有 Undefined array key "prefix" 或 Class App\Http\Controllers\HomeController does not exist ——八成是缓存没清。Laravel 的配置、路由、视图缓存互不干扰,漏一个就卡一个环节。
- 按顺序清三类缓存:
php artisan config:clear→php artisan route:clear→php artisan view:clear - 别依赖
php artisan optimize:clear,它在 Laravel 11 中已被移除,强行运行会报命令不存在 - 如果用了 OPCache,还得在 CLI 和 Web Server 两处分别重启:
sudo service php8.2-fpm restart+sudo systemctl reload apache2(根据实际环境调整)
最麻烦的不是命令不会敲,而是升级后某个队列任务突然不触发、某条 API 返回空数组、或者日志里持续刷 Deprecated: str_plural() 却找不到调用位置——这类问题往往藏在第三方包或自定义宏里。建议升级完立刻跑一次 grep -r "str_" app/ --include="*.php" 和 grep -r "array_" app/ --include="*.php",把辅助函数调用全揪出来替换成 Str::/Arr::。这步省不下。










