不能直接从 Laravel 8.x 升级到 10.x,必须先升级至 9.x 再升级至 10.x;需检查 PHP ≥8.1、更新不兼容包、显式声明控制器类名、避免 DBAL change() 破坏外键、彻底清除四类缓存,并注意废弃行为与配置变更。

确认是否真能直接升到 Laravel 10
不能从 8.x 或更早版本一步跳到 10.x,Laravel 官方明确要求逐级升级:9.x → 10.x 是唯一安全路径。跨版本会触发大量未声明的破坏性变更,比如 Route::controller() 在 10 中已被彻底移除,而 8→10 的迁移脚本根本不会提示你改这个。
- 先运行
composer show laravel/framework确认当前版本;若低于 9.x,必须先升到 9.x,再升 10.x - 检查 PHP 版本:Laravel 10 要求
PHP >= 8.1,CentOS 上常卡在 8.0,得先升级 PHP(如用 Remi 仓库) - 运行
composer outdated查看哪些第三方包不兼容——像laravel/socialitev5 不支持 Laravel 10,得升到 v5.12+ 才行
路由命名空间失效?不是 Bug 是设计变更
Laravel 10 默认关闭了路由组的自动命名空间绑定,Route::group(['namespace' => 'App\Http\Controllers']) 这种写法依然能跑,但已废弃且不再生效。所有控制器引用必须显式写出完整类名,否则会报 Class App\Http\Controllers\HomeController does not exist。
- 把
routes/web.php里所有类似'HomeController@index'的字符串写法,全换成数组语法:[App\Http\Controllers\HomeController::class, 'index'] - 配合
use语句简化:顶部加use App\Http\Controllers\HomeController;,然后写成[HomeController::class, 'index'] - 别漏掉
api.php和任何自定义路由文件;中间件组、资源路由里的控制器也得同步改
外键突然没了?Doctrine DBAL 升级惹的祸
升级后执行 php artisan migrate,发现外键约束全部消失,但数据还在——这不是 Laravel 删的,是 Doctrine DBAL v3.5+ 在 change() 字段时默认重建表结构,而重建过程不保留原有外键。
- 避免对含外键的字段直接用
change(),比如$table->string('email', 191)->change() - 改用三步法:先
dropForeign(),再change(),最后foreign()重建(注意字段类型要严格一致,如unsignedBigInteger) - 开发环境启用
DB_FOREIGN_KEYS=true并在迁移开头加Schema::enableForeignKeyConstraints();,可提前暴露问题
升级后页面白屏或配置错乱?缓存没清干净
php artisan config:cache 会把旧版配置硬编码进 bootstrap/cache/config.php,而 Laravel 10 的 config/logging.php 结构已重写,缓存未更新就会导致日志驱动崩溃、甚至整个应用无法启动。
- 升级后第一件事不是测功能,而是连清四缓:
php artisan config:clear && php artisan cache:clear && php artisan view:clear && php artisan route:clear - 别急着
config:cache,先跑一遍php artisan tinker,手动验证config('app.name')、config('database.connections.mysql')是否读取正确 - 如果用了 Envoy 或 Horizon,它们的配置也得单独检查,
HORIZON_PREFIX在 10 中默认值变了
实际升级中最容易被忽略的,是那些“没报错但行为已变”的点:比如 Request::segment(1) 在 10 中仍可用,但官方文档已标记为废弃,下个大版本就删;又比如 APP_URL 现在影响 CSRF token 生成逻辑,值末尾多一个 / 都会导致前端请求被拒绝。这些细节不会中断部署,但会在上线后悄悄咬你一口。











