laravel老项目升级本质是验证旧代码在新环境中的契约兼容性,需检查php版本(11要求8.2+)、迁移类名与文件名一致性、废弃方法(如unsignedinteger)、外键约束默认禁用及命名参数语法等,避免“无报错但结果错误”。

装老项目和装新项目,本质不是“装不装”的问题,而是“能不能让旧代码在新环境里活下来”。Laravel 5.4 和 Laravel 11 的底层契约、自动加载规则、迁移语法、甚至 PHP 版本要求都可能不兼容——直接用新命令跑老代码,大概率报 Class not found、Undefined method 或直接语法错误。
composer create-project 装新项目,但老项目不能这么来
新项目用 composer create-project laravel/laravel:^11 myapp 一行搞定,所有目录结构、配置、vendor 自动对齐 Laravel 11。老项目不行:它已经有 composer.json,但里面可能锁着 "laravel/framework": "5.4.*";它可能有自定义的 app/Providers/CustomServiceProvider.php,而 Laravel 6+ 已移除 App\Providers\AppServiceProvider::boot() 里的某些魔术方法调用;它的 routes/web.php 里还写着 Route::get('/', 'HomeController@index'),而 Laravel 8+ 默认启用了控制器类引用语法,但没配命名空间就直接挂掉。
- 别删老项目的
composer.json重拉——依赖树全崩,第三方包(比如barryvdh/laravel-debugbar)版本可能只支持到 Laravel 7 - 升级前先运行
composer why-not laravel/framework:11,看清是哪个包卡住了升级路径 - 老项目若含大量
App\Http\Controllers\Controller继承链,得确认是否已迁移到Illuminate\Routing\Controller(Laravel 9+ 移除了前者)
迁移文件名和类名必须严格一致(Laravel 6+ 强制)
老项目迁移文件可能是 2014_10_12_000000_create_users_table.php,但类名写成 CreateUserTable 或 CreateUsersTableMigration —— 这在 Laravel 5.8 及以前能跑,Laravel 6+ 直接拒绝加载,php artisan migrate:status 显示 “N” 却查不到错在哪。
- 检查每个迁移文件:类名必须和文件名去掉时间戳和下划线后的驼峰形式完全一致,例如
2020_01_01_123456_add_status_to_posts.php→ 类名必须是AddStatusToPosts - 执行
composer dump-autoload是必须动作,尤其跨主版本(如 5.8 → 6.x)后,否则自动加载器根本找不到类 - 如果迁移已手动在数据库建过表,但状态显示未运行,别删表重来——先用
php artisan migrate:rollback --step=1测试能否回滚,失败就说明类加载或语法有问题
PHP 版本和迁移语法是隐形断点
Laravel 8 支持 PHP 7.3+,Laravel 11 要求 PHP 8.2+。老项目迁移里如果写了 $table->string(column: 'title'),这是 PHP 8.0+ 命名参数语法,在 PHP 7.4 环境下直接解析失败,报 syntax error, unexpected ':',错误堆栈甚至不指向迁移文件本身,而是 vendor/autoload.php 后面某行。
- 用
php -l database/migrations/xxx.php逐个检查迁移文件语法,比等php artisan migrate报错更早发现问题 -
unsignedInteger()在 Laravel 9+ 已废弃,老项目若用它建外键字段,constrained()会静默失效——得换成unsignedBigInteger('user_id') - Laravel 9+ 默认禁用外键约束,
Schema::create()内部自动调用disableForeignKeyConstraints(),所以即使你写了$table->foreignId('category_id')->constrained(),生成的 SQL 也可能没外键
最麻烦的不是报错,而是“没报错但结果不对”:迁移看似成功,字段类型变了、索引丢了、外键没建——这种问题往往要上线后才发现,而且很难复现。老项目升级,重点不在“怎么升”,而在“升之前怎么验证每一处契约是否还成立”。











