能升,但必须从 laravel 9.x 升到 10.x,不能跳过;php 必须 ≥8.1.0,composer ≥2.2.0,且需更新依赖、路由语法、迁移写法并清除全部缓存。

能升,但必须从 Laravel 9.x 升到 10.x,不能跳过;PHP 必须 ≥8.1.0,否则 composer update 直接失败。
检查环境是否满足硬性门槛
升级不是改个版本号就能跑起来的事,Laravel 10 对底层有明确限制:
- 运行
php -v确认 PHP ≥8.1.0 —— 如果是 8.0 或更低,composer update会报错:Your requirements could not be resolved - 运行
composer --version确认 Composer ≥2.2.0 —— 旧版可能无法解析 Laravel 10 的依赖约束 - 运行
php artisan --version确认当前是 9.x(如Laravel Framework 9.52.15),不是 8.x 或更早;若是 8.x,必须先升到 9.x 再升 10.x - 运行
composer outdated查看第三方包兼容性,重点关注:laravel/sanctum≥^3.2、doctrine/dbal≥^3.0、spatie/laravel-ignition≥^2.0
修改 composer.json 并执行更新
写错一个字符就可能拉不下来包,或引入隐性冲突:
- 把
"laravel/framework": "^9.0"改成"laravel/framework": "^10.0" - 同步更新配套依赖:
"nunomaduro/collision": "^7.0"、"spatie/laravel-ignition": "^2.0"、"phpunit/phpunit": "^10.0" - 删掉
"minimum-stability": "dev"这类非稳定设置,改成"minimum-stability": "stable",否则可能装入 alpha/beta 版本 - 执行
composer update --with-all-dependencies—— 推荐加这个参数,避免部分子依赖被跳过导致运行时报Class not found
路由控制器写法必须显式声明类名
Laravel 10 默认关闭了路由组的自动命名空间绑定,Route::group(['namespace' => 'App\Http\Controllers']) 这种写法已废弃且不生效:
- 把
routes/web.php里所有类似'HomeController@index'的字符串写法,全部换成数组语法:[App\Http\Controllers\HomeController::class, 'index'] - 顶部加
use App\Http\Controllers\HomeController;,然后简写为[HomeController::class, 'index'] - 别漏掉
api.php、资源路由(Route::resource())、中间件组里的控制器引用 -
Route::controller()在 Laravel 10 中已被彻底移除,相关写法必须重构成单条路由
外键消失?DBAL change() 是罪魁祸首
升级后执行 php artisan migrate,发现外键全没了但数据还在 —— 这不是 Laravel 删的,是 doctrine/dbal v3.5+ 在 change() 字段时默认重建表结构,而重建过程不保留原有外键:
- 避免对含外键的字段直接用
change(),比如$table->string('email', 191)->change() - 改用三步法:先
dropForeign(),再change(),最后foreign()重建(注意字段类型要严格一致,如unsignedBigInteger) - 开发环境建议在迁移开头加
Schema::enableForeignKeyConstraints();,并确保DB_FOREIGN_KEYS=true,可提前暴露问题
升级后最常被忽略的是缓存残留 —— php artisan config:cache 会把旧版 config/logging.php 结构硬编码进 bootstrap/cache/config.php,而 Laravel 10 的日志配置已重写,缓存未清会导致日志驱动崩溃甚至整个应用无法启动。务必执行 php artisan config:clear && php artisan route:clear && php artisan view:clear && php artisan cache:clear 四清。











