跳转到主要内容

前言

Laravel 10 于 2023 年 2 月 14 日发布。本指南讲解从 Laravel 9.x 升级到 10.x 的步骤。
预计升级时间约 10 分钟。当然,破坏性变更对应用的影响会因规模和所用功能而异。

用 Laravel Shift 自动升级

也可以用 Laravel Shift 自动化升级。Shift 会自动更新应用的依赖和配置文件。

按影响面分级的变更

影响度:高

  • 依赖更新
  • 更新 minimum-stability

影响度:中

  • 数据库 Expression 变更
  • 移除模型的 $dates 属性
  • Monolog 3
  • Redis 缓存 tags
  • 服务 mock 变更
  • 语言目录

影响度:低

  • 闭包校验规则的消息
  • Form Request 的 after 方法
  • 公共路径绑定
  • QueryException 构造函数
  • 限流器的返回值
  • 移除 Redirect::home 方法
  • 移除 Bus::dispatchNow 方法
  • registerPolicies 方法
  • ULID 列

升级步骤

更新依赖

影响度:高 请更新 composer.json 中的以下依赖。
{
  "require": {
    "laravel/framework": "^10.0",
    "laravel/sanctum": "^3.2",
    "doctrine/dbal": "^3.0",
    "spatie/laravel-ignition": "^2.0"
  }
}
如果用了以下包,请一并升级。
{
  "require": {
    "laravel/passport": "^11.0",
    "laravel/ui": "^4.0"
  }
}
使用 PHPUnit 10 时也请更新:
{
  "require-dev": {
    "nunomaduro/collision": "^7.0",
    "phpunit/phpunit": "^10.0"
  }
}
使用 PHPUnit 10 时,请从 phpunit.xml<coverage> 部分删除 processUncoveredFiles 属性。
之后执行:
composer update
从 Sanctum 2.x 升到 3.x,请另外查阅 Sanctum 3.x 升级指南

更新 minimum-stability

影响度:高 composer.jsonminimum-stability 更新为 stable。因为默认值就是 stable,你也可以直接删掉这项。
"minimum-stability": "stable"

PHP 版本要求

影响度:高 Laravel 10 需要 PHP 8.1.0 及以上Composer 2.2.0 及以上

破坏性变更(Breaking Changes)

应用

公共路径绑定

影响度:低 如果你通过绑定 path.public 来自定义公共路径,请改用 Illuminate\Foundation\ApplicationusePublicPath 方法。
app()->usePublicPath(__DIR__.'/public');

授权

registerPolicies 方法

影响度:低 AuthServiceProviderregisterPolicies 方法现在由框架自动调用。可以从 boot 方法中删除对它的调用。

缓存

Redis 缓存 tags

影响度:中 Cache::tags() 仅建议在使用 Memcached 的应用中使用。使用 Redis 作为缓存驱动时,建议迁移到 Memcached。

数据库

数据库 Expression 变更

影响度:中 DB::raw 生成的数据库 Expression 被重写。要拿到 Expression 的原始字符串值,需要用 getValue(Grammar $grammar) 方法。不能再用 (string) 强转。
use Illuminate\Support\Facades\DB;

$expression = DB::raw('select 1');

// Before
$string = (string) $expression;

// After
$string = $expression->getValue(DB::connection()->getQueryGrammar());
普通终端应用一般不会受到影响,但只要你有对数据库 Expression 做字符串强转,就需要修改。

QueryException 构造函数

影响度:非常低 Illuminate\Database\QueryException 的构造函数第一个参数增加了字符串类型的连接名。如果你手动抛这个异常,需要相应修改。

ULID 列

影响度:低 在迁移里不带参数调用 ulid 方法时,列名会是 ulid。以前不带参数调用会错误地创建名为 uuid 的列。
// 列名会是 "ulid"
$table->ulid();

// 明确指定列名
$table->ulid('ulid');

Eloquent

模型的 $dates 属性

影响度:中 Eloquent 模型上已废弃的 $dates 属性被移除。请改用 $casts
// Before
protected $dates = ['deployed_at'];

// After
protected $casts = [
    'deployed_at' => 'datetime',
];

本地化

语言目录

影响度:无 对已有应用没有影响,但新的 Laravel 应用骨架默认不再包含 lang 目录。需要时可以用 Artisan 命令发布。
php artisan lang:publish

日志

Monolog 3

影响度:中 Laravel 对 Monolog 的依赖升到了 Monolog 3.x。如果你在应用里直接使用 Monolog,请查阅 Monolog 的升级指南 使用 BugSnag、Rollbar 等第三方日志服务时,可能需要升级到支持 Monolog 3.x 与 Laravel 10.x 的版本。
Monolog 3.x 的变更点可以在 Monolog 3.x 升级指南 中查看。

队列

移除 Bus::dispatchNow 方法

影响度:低 已废弃的 Bus::dispatchNowdispatch_now 方法被移除。请使用 Bus::dispatchSyncdispatch_sync
// Before
Bus::dispatchNow(new MyJob());
dispatch_now(new MyJob());

// After
Bus::dispatchSync(new MyJob());
dispatch_sync(new MyJob());

路由

中间件别名

影响度:任选 新的 Laravel 应用里,App\Http\Kernel 类的 $routeMiddleware 属性改名为 $middlewareAliases。要不要在已有应用里跟着改是你的自由。

限流器的返回值

影响度:低 调用 RateLimiter::attempt 时,你提供的闭包的返回值会被原样返回。什么都不返回或返回 null 时,会返回 true
$value = RateLimiter::attempt('key', 10, fn () => ['example'], 1);

$value; // ['example']

移除 Redirect::home 方法

影响度:非常低 已废弃的 Redirect::home 方法被移除。请显式改为命名路由跳转。
// Before
return Redirect::home();

// After
return Redirect::route('home');

测试

服务 mock

影响度:中 已废弃的 MocksApplicationServices trait 从框架中移除。它曾经提供 expectsEventsexpectsJobsexpectsNotifications 等测试方法。 如果你还在用这些方法,请分别迁移到 Event::fakeBus::fakeNotification::fake
// Before
$this->expectsEvents(OrderShipped::class);

// After
Event::fake();
// ... 测试代码 ...
Event::assertDispatched(OrderShipped::class);

校验

闭包校验规则的消息

影响度:非常低 在基于闭包的自定义校验规则里多次调用 $fail 回调时,消息不再是被覆盖,而是追加到数组中。 同时,$fail 回调现在返回对象。如果你为校验闭包的返回值加了类型提示,需要相应修改。
public function rules()
{
    return [
        'name' => [
            function ($attribute, $value, $fail) {
                $fail('validation.translation.key')->translate();
            },
        ],
    ];
}

Form Request 的 after 方法

影响度:非常低 Form Request 里的 after 方法名被 Laravel 保留。如果你在 Form Request 上定义了 after 方法,请重命名或改造,让它用上新的“校验后”机制。

总结

Laravel 10 的变更相对小,可以在很短时间内完成升级。
变更点影响度应对
composer.json 依赖更新改为 laravel/framework ^10.0
必须 PHP 8.1 / Composer 2.2检查并更新版本
数据库 Expression 变更(string) 强转改为 getValue()
移除模型 $dates 属性迁移到 $casts
Monolog 3直接使用时请查阅升级指南
Redis 缓存 tags考虑迁移到 Memcached
移除 MocksApplicationServices迁移到 Event::fake
移除 Bus::dispatchNow改为 Bus::dispatchSync
ULID 列名检查迁移中的 ulid() 调用
移除 Redirect::home非常低改为 Redirect::route('home')

参考资料

最后修改于 2026年7月13日