前言
Laravel 11 于 2024 年 3 月发布。本指南讲解从 Laravel 10.x 升级到 11.x 的操作步骤。预计升级时间约 15 分钟。当然,破坏性变更对应用的影响会因规模和所用功能而异。
用 Laravel Shift 自动升级
也可以用 Laravel Shift 自动化升级。Shift 会自动更新应用的依赖和配置文件。按影响面分级的变更
影响度:高
- 依赖更新
- 应用目录结构变更
- 浮点类型变更
- 列变更时属性保留
- SQLite 最低版本
- Sanctum 更新
影响度:中
- Carbon 3
- 登录时重新哈希密码
- 秒级限流
- Spatie Once 包
影响度:低
- 移除 Doctrine DBAL
- Eloquent 模型的
casts方法 - 空间类型变更
Enumerable契约UserProvider契约Authenticatable契约
升级步骤
更新依赖
影响度:高 请更新composer.json 中的以下依赖。
doctrine/dbal,现在可以移除了。Laravel 11 不再依赖它。
PHP 版本要求
影响度:高 Laravel 11 需要 PHP 8.2.0 或以上。Laravel 的 HTTP Client 需要 curl 7.34.0 或以上。应用目录结构变更
影响度:高 Laravel 11 简化了默认的应用目录结构。服务提供者、中间件、配置文件的数量都大幅减少。 不过,把 Laravel 10 的应用升级到 Laravel 11 时,不建议同时迁移目录结构。Laravel 11 从设计上就支持沿用 Laravel 10 的目录结构。 主要结构变化:- 在
bootstrap/app.php中直接配置中间件、异常处理、路由 - 废弃
app/Http/Kernel.php,合并进bootstrap/app.php - 减少默认服务提供者数量,并改由
bootstrap/providers.php管理 - 减少
config/目录里的文件数量(需要时可用php artisan config:publish发布)
破坏性变更(Breaking Changes)
认证
密码的重新哈希
影响度:中 Laravel 11 会在认证时检测哈希算法的“work factor”是否变化,自动重新哈希密码。 如果User 模型的密码字段名不是 password,请通过模型的 authPasswordName 属性指明。
config/hashing.php 中加上:
UserProvider 契约
影响度:低
Illuminate\Contracts\Auth\UserProvider 契约新增了 rehashPasswordIfRequired 方法。如果你有实现该接口的类,请补上这个方法。
Authenticatable 契约
影响度:低
Illuminate\Contracts\Auth\Authenticatable 契约新增了 getAuthPasswordName 方法。如果你有实现该接口的类,请补上。
数据库
SQLite 最低版本
影响度:高 使用 SQLite 时需要 SQLite 3.26.0 或以上。 顺带一提,Laravel 11 新项目的默认数据库驱动改成了 SQLite。列变更时保留属性
影响度:高 修改列时,你必须显式指定所有想保留的修饰符。没有指明的属性会被删掉。浮点类型变更
影响度:高double 和 float 迁移列类型在各数据库间被统一了。
unsignedDecimal、unsignedDouble、unsignedFloat 方法被移除。要继续使用 unsigned 属性,请以方法链的方式加。
Eloquent 模型的 casts 方法
影响度:低
Eloquent 基类中定义了 casts 方法。如果你在应用的模型中定义了名为 casts 的关联,会出现命名冲突,需要重命名。
MariaDB 专用驱动
影响度:非常低 Laravel 11 加入了针对 MariaDB 的专用数据库驱动。连接 MariaDB 时可以在配置中使用mariadb 驱动。
空间类型变更
影响度:低 空间列类型在各数据库间被统一了。不再使用point、lineString、polygon 等方法,请改用 geometry 或 geography。
subtype 和 srid。
移除 Doctrine DBAL
影响度:低 Laravel 移除了对 Doctrine DBAL 的依赖。下面这些类和方法也一并被移除:Schema\Builder::useNativeSchemaOperationsIfPossible()Connection::getDoctrineConnection()Connection::getDoctrineSchemaManager()Connection::registerDoctrineType()DatabaseManager::registerDoctrineType()Schema\Grammars\ChangeColumn类Schema\Grammars\RenameColumn类
Schema::getTables()、Schema::getColumns()、Schema::getIndexes()、Schema::getForeignKeys() 等新的原生方法。
日期
Carbon 3
影响度:中 Laravel 11 同时支持 Carbon 2 和 Carbon 3。升级到 Carbon 3 时要注意,diffIn* 方法现在返回浮点数,并用负数表示时间方向。
限流
秒级限流
影响度:中 Laravel 11 支持了以秒为单位的限流。GlobalLimit、Limit 类的构造函数现在接受秒数。
Limit 类的 decayMinutes 属性重命名为 decaySeconds,单位变为秒。
ThrottlesExceptions 和 ThrottlesExceptionsWithRedis 的构造函数也改为接受秒。
包
服务提供者的发布
影响度:非常低 Laravel 11 新项目的config/app.php 中不再有 providers 数组。包中要发布服务提供者时,请用 ServiceProvider::addProviderToBootstrapFile 方法。
Sanctum
Sanctum 升级
影响度:高 Laravel 11 不支持 Sanctum 3.x。请把composer.json 中的 Sanctum 依赖升到 ^4.0。
Sanctum 4.0 不再自动加载迁移,请通过下面的命令发布迁移。
config/sanctum.php 里的中间件配置。
Spatie Once 包
影响度:中 Laravel 11 提供了自己的once 函数。如果你在使用 spatie/once 包,为避免冲突,请把它从 composer.json 中移除。
总结
Laravel 11 带来了较大的结构性变化,但由于它兼容 Laravel 10 的目录结构,可以按阶段推进迁移。| 变更点 | 影响度 | 应对 |
|---|---|---|
composer.json 依赖更新 | 高 | 改为 laravel/framework ^11.0 |
| 必须 PHP 8.2 | 高 | 检查 PHP 版本 |
| 列变更时属性保留 | 高 | 检查使用 change() 的位置 |
| 浮点类型变更 | 高 | 检查 double/float 列定义 |
| 必须 SQLite 3.26.0+ | 高 | 检查 SQLite 版本 |
Sanctum ^4.0 | 高 | 发布迁移 |
| Carbon 3 | 中 | 检查 diffIn* 的返回值 |
| 秒级限流 | 中 | 把 decayMinutes 改为 decaySeconds |
| 移除 Doctrine DBAL | 低 | 迁移到原生 schema 方法 |