Laravel 11 升级指南
更多 Laravel 11 更新内容,请查看此处:https://tubring.cn/articles/laravel-11-preview
高影响更新
- 更新依赖
- 应用结构
- 浮点型类型
- 修改数据库字段
- SQLite 最低版本
- 更新 Sanctum
中等影响更新
- Carbon 3
- 密码重新哈希
- 按秒限流
低影响更新
- 移除 Doctrine DBAL
- Eloquent 模型的
casts
方法 - Spatial 类型
- Spatie Once 包
Enumerable
ContractUserProvider
ContractAuthenticatable
Contract
从 10.x 升级到 11.0
预计升级时间:15分钟
我们试图每一个可能的破坏性更新记入文档。由于这些破坏性更新中有一些位于框架的模糊部分,因此只有其中的一部分更改可能会实际影响你的应用。想节省时间吗?您可以使用 Laravel Shift 来帮助实现应用升级的自动化。
更新依赖
影响可能性:高
要求 PHP 8.2.0
Laravel 现在要求 PHP 8.2.0 及以上版本。
Composer 依赖
你应该再应用的composer.json
文件中更新以下依赖
laravel/framework
to^11.0
nunomaduro/collision
to^8.1
laravel/cashier-stripe
to^15.0
(如果安装了)laravel/passport
to^12.0
(如果安装了)laravel/sanctum
to^4.0
(如果安装了)laravel/spark-stripe
to^5.0
(如果安装了)laravel/telescope
to^5.0
(如果安装了)
如果您的应用程序使用的是 Laravel Cashier Stripe、Passport、Sanctum、Spark Stripe 或 Telescope,则需要将它们的迁移发布到应用中。Cash Stripe、Passport、Sanctum、Spark Stripe 和 Telescope 不再自动从它们自己的迁移目录加载迁移。因此,你应该运行以下命令将迁移发布到你的应用中:
php artisan vendor:publish --tag=cashier-migrations
php artisan vendor:publish --tag=passport-migrations
php artisan vendor:publish --tag=sanctum-migrations
php artisan vendor:publish --tag=spark-migrations
php artisan vendor:publish --tag=telescope-migrations
此外,你应该查看每个包的升级指南,以确保你了解其他任何破坏性的更改:
如果你手动安装了 Laravel installer,你应该通过 Composer 更新 installer:
composer global require laravel/installer:^5.6
最后,如果你之前已将 doctrine/dbal
依赖项添加到应用程序中,则可以删除它,因为 Laravel 不再依赖于此包。
应用结构
Laravel 11 引入了一种新的默认应用程序结构,其默认文件更少。也就是说,新的 Laravel 应用包含更少的服务提供者、中间件和配置文件。
然而,我们不建议升级到 Laravel 11 的 Laravel 10 应用尝试迁移其应用结构,因为 Laravel 已经经过精心调整,也支持 Laravel 10 的应用结构。
身份验证
密码重新哈希
如果您的哈希算法的“工作因子”自上次哈希密码以来已经更新,Laravel 11 将在身份验证期间自动重新哈希用户的密码。
通常情况下,这不会破坏你的应用;但是,你可以通过将 rehash_on_login
选项添加到应用的 config/hashing.php
配置文件中来禁用此行为:
'rehash_on_login' => false,
UserProvider
Contract
影响可能性:低
Illuminate\Contracts\Auth\UserProvider
contract 接受一个新的 rehashPasswordIfRequired
方法。当应用程序的哈希算法工作因子发生变化时,此方法负责重新哈希并将用户密码存到在 storage 中。
如果应用或包定义了实现此接口的类,则应将新的 rehashPasswordIfRequired
方法添加到实现中。可以在 Illuminate\Auth\EloquentUserProvider
类中找到参考实现:
public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false);
Authenticatable
Contract
影响可能性:低
Illuminate\Contracts\Auth\Authenticatable
contract 已接收到新的 getAuthPasswordName
方法。此方法负责返回可认证实体的密码列的名称。
如果你的应用或包定义了实现此接口的类,则应将新的 getAuthPasswordName
方法添加到实现中:
public function getAuthPasswordName()
{
return 'password';
}
Laravel 中包含的默认 User
模型会自动接收此方法,因为该方法包含在 Illuminate\Auth\Authenticatable
trait 中。
缓存
缓存密钥前缀
影响可能性:低
以前,如果为 DynamoDB、Memcached 或 Redis 缓存存储定义了缓存密钥前缀,Laravel 会在前缀后附加一个 :
。在 Laravel 11 中,缓存密钥前缀不接收 :
后缀。如果您想保持以前的前缀行为,可以手动将 :
后缀添加到缓存密钥前缀中。
集合
Enumerable
Contract
影响可能性:低
Illuminate\Support\Enumerable
Contract的转储方法已更新为接受可变 ...$args
参数。如果你实现了此接口,则应相应地更新你的实现:
public function dump(...$args);
数据库
SQLite 3.35.0+
影响可能性:高
如果你的应用程序正在使用 SQLite 数据库,则需要使用 SQLite 3.35.0 或更高版本。
Eloquent 模型 casts
方法
影响可能性:低
基础的 Eloquent 模型类现在定义了一个 casts
方法,以便支持属性强制转换的定义。如果应用的某个模型定义了 casts
关联,则它可能与基础 Eloquent 模型类上现在存在的 casts
方法冲突。
修改数据库字段
影响可能性:高
当修改字段时,现在必须显式包含更改后要保留在字段定义上的所有修饰符。任何丢失的属性都将被删除。例如,要保留 unsigned
、default
和 comment
属性,在更改列时必须显式调用每个修饰符,即使这些属性已由以前的迁移分配给该字段。
比如,假设你有一个迁移,使用了 unsigned
、default
和 comment
属性来创建 votes
字段:
Schema::create('users', function (Blueprint $table) {
$table->integer('votes')->unsigned()->default(1)->comment('The vote count');
});
稍后,你将编写一个迁移,将该列也更改为 nullable
:
Schema::table('users', function (Blueprint $table) {
$table->integer('votes')->nullable()->change();
});
在 Laravel 10 中,此迁移将保留该字段上的 unsigned
、default
和 comment
属性。然而,在 Laravel 11 中,迁移现在还必须包括以前在该字段上定义的所有属性。否则,它们将被丢弃:
Schema::table('users', function (Blueprint $table) {
$table->integer('votes')
->unsigned()
->default(1)
->comment('The vote count')
->nullable()
->change();
});
change()
方法不会修改该字段的索引。因此你可以在修改该字段时使用索引修饰符来显式添加或者删除索引:
// Add an index...
$table->bigIncrements('id')->primary()->change();
// Drop an index...
$table->char('postal_code', 10)->unique(false)->change();
如果你不想更新应用所有现有的“更改”迁移以保留该字段的现有属性,你可以简单地压缩迁移:
php artisan schema:dump
一旦您的迁移被压缩,Laravel 将在运行任何挂起的迁移之前使用应用的 schema 文件“迁移”数据库。
浮点类型
影响可能性:高
double
和 float
迁移字段类型已被重写,以便在所有数据库中保持一致。
现在,double
字段类型创建了一个 DOUBLE
等效字段,不包含总位数和位数(小数点后的位数),这是标准的 SQL 语法。因此,你可以删除$total
和 $places
的参数:
$table->double('amount');
float
字段类型现在创建了一个 FLOAT
等效字段,该列没有总位数和位数(小数点后的位数),但具有可选的 $precision
规范,用于将存储大小确定为 4字节单精度字段或8 字节双精度字段。因此,你可以删除 $total
和 $places
的参数,并根据数据库文档将可选的$precision
指定为所需值:
$table->float('amount', precision: 53);
unsignedDecimal
、 unsignedDouble
和 unsignedFloat
方法已被移除,因为这些字段类型的 unsigned 修饰符已被 MySQL 弃用,而且在其他数据库系统中从未标准化。不过,如果你项继续让这些字段类型使用这些弃用的 unsigned 属性,你可以在字段定义中链式调用 unsigned
方法:
$table->decimal('amount', total: 8, places: 2)->unsigned();
$table->double('amount')->unsigned();
$table->float('amount', precision: 53)->unsigned();
MariaDB 专用驱动
影响可能性:非常低
Laravel 11 在连接 MariaDB 数据库时不总是使用 MySQL 驱动,而是为 MariaDB 添加了一个专用的数据库驱动。
如果你的应用连接到 MariaDB 数据库,你可以将连接配置更新到新的MariaDB 驱动程序,以在未来受益于 MariaDB 的特定功能:
'driver' => 'mariadb',
'url' => env('DB_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
// ...
目前,新增的 MariaDB 驱动的行为与当前的 MySQL 驱动类似,但有一个例外:uuid
schema 生成器方法创建原生 UUID 字段,而不是 char(36)
字段。
如果你现有的迁移使用 uuid
schema 生成器方法,并且你选择使用新的 mariadb
数据库驱动,则应将迁移对 uuid
方法的调用更新为 char
,以避免破坏性变化或意外行为:
Schema::table('users', function (Blueprint $table) {
$table->char('uuid', 36);
// ...
});
Spatial 空间类型
影响可能性:低
数据库迁移的 spatial 字段类型已被重写,以使所有数据库保持一致。因此你可以在数据库迁移中删除 point
、lineString
、 polygon
、 geometryCollection
、multiPoint
,multiLineString
、multiPolygon
和 multiPolygonZ
方法并替换成 geometry
或者 geography
:
$table->geometry('shapes');
$table->geography('coordinates');
要明确限制 MySQL、MariaDB 和 PostgreSQL 上存储在字段的值的类型或空间引用系统标识符,可以将 subtype
和 srid
传递给方法:
$table->geometry('dimension', subtype: 'polygon', srid: 0);
$table->geography('latitude', subtype: 'point', srid: 4326);
PostgreSQL 语法的 isGeometry
和 projection
字段修饰符也被相应地移除。
Doctrine DBAL 移除
影响可能性:低
以下与 Doctrine DBAL 相关的类和方法列表已删除。Laravel 不再依赖于此包,注册自定义 Doctrines 类型对于正确创建和更改以前需要自定义类型的各种字段类型不再是必要的:
Illuminate\Database\Schema\Builder::$alwaysUsesNativeSchemaOperationsIfPossible
类属性Illuminate\Database\Schema\Builder::useNativeSchemaOperationsIfPossible()
方法Illuminate\Database\Connection::usingNativeSchemaOperations()
方法Illuminate\Database\Connection::isDoctrineAvailable()
方法Illuminate\Database\Connection::getDoctrineConnection()
方法Illuminate\Database\Connection::getDoctrineSchemaManager()
方法Illuminate\Database\Connection::getDoctrineColumn()
方法Illuminate\Database\Connection::registerDoctrineType()
方法Illuminate\Database\DatabaseManager::registerDoctrineType()
方法Illuminate\Database\PDO
目录Illuminate\Database\DBAL\TimestampType
类Illuminate\Database\Schema\Grammars\ChangeColumn
类Illuminate\Database\Schema\Grammars\RenameColumn
类Illuminate\Database\Schema\Grammars\Grammar::getDoctrineTableDiff()
方法
此外,不再需要通过 dbal.types
在应用的 database
数据库配置文件中注册自定义 Doctrine 类型。
如果您以前使用 Doctrine DBAL 检查数据库及其相关表,则可以使用 Laravel 的新原生 schema 方法(Schema::getTables()
, Schema::getColumns()
, Schema::getIndexes()
, Schema::getForeignKeys()
等)。
弃用 Schema 方法
影响可能性:非常低
基于 Doctrine 的 Schema::getAllTables()
、Schema::getAllViews()
和 Schema::getAllTypes()
方法已被移除,取而代之的是 Schema::getTables()
、Schema::getViews()
和 Schema::getTypes()
方法。
当使用 PostgreSQL 和 SQL Server 时,新的 schema 方法都不接受第三方引用(比如 database.schema.table
。因此,你应该使用 connection()
来声明数据库来替代:
Schema::connection('database')->hasTable('schema.table');
Schema Builder getColumnType()
方法
影响可能性:非常低
Schema::getColumnType()
方法现在返回的是戈丁字段的实际类型,不再是 Doctrine DBAL 的等效类型。
数据库连接接口
影响可能性:非常低
Illuminate\Database\ConnectionInterface
接口接收一个新的 scalar
方法。如果你自己定义了该接口的实现,应该将 scalar
方法添加到实现中:
public function scalar($query, $bindings = [], $useReadPdo = true);
Date
Carbon 3
影响可能性:中
Laravel 11 支持 Carbon 2 和 Carbon 3。Carbon 是一个日期操作库,被 Laravel 和整个生态系统的包广泛使用。如果你安装了 Carbon 3,应该查看 Carbon 的更新日志。
Mailer
Contract
影响可能性:非常低
Illuminate\Contracts\Mail\Mailer
contract 接收了一个新的 sendNow
方法。如果你的应用或包手动实现了该 contract,你应该将新增的 sendNow
添加到实现中:
public function sendNow($mailable, array $data = [], $callback = null);
包
发布服务提供者到应用中
影响可能性:非常低
如果你编写了一个 Laravel 包,该包手动将服务提供者序发布到应用程序的 app/Providers
目录,并手动修改应用的 config/app.php
配置文件以注册服务提供者,则应更新你的包以使用新的 ServiceProvider::addProviderToBootstrapFile
方法。
addProviderToBootstrapFile
方法将自动将你发布的服务提供者添加到应用程序的 bootstrap/providers.php
文件中,因为在新的 Laravel 11 应用程序的 config/app.php
配置文件中不存在 providers
数组。
use Illuminate\Support\ServiceProvider;
ServiceProvider::addProviderToBootstrapFile(Provider::class);
队列
BatchRepository
接口
影响可能性:非常低
Illuminate\Bus\BatchRepository
接口接收一个新的 rollBack
方法。如果你在自己的包或应用中实现了该接口,你应该将该方法添加到实现中:
public function rollBack();
数据库交易中的同步任务(Job)
影响可能性:非常低
此前,同步任务(使用 sync
队列驱动的任务)将会立即执行,尽管队列连接的 after_commit
配置项设置为 true
还是任务调用了 afterCommit
方法。
在 Laravel 11 中,同步队列任务现在将“尊重”队列连接或任务的“ after commit” 配置。
限流
每秒限流
影响可能性:中
Laravel 11 支持每秒速率限制,而不是限制为每分钟颗粒度。你应该注意与此变化相关的各种潜在的破坏性变化。
GlobalLimit
类构造函数现在接受秒而不是分钟。此类没有文档记录,通常不会被你的应用使用:
new GlobalLimit($attempts, 2 * 60);
Limit
类构造函数现在接受秒而非分钟。该类的所有文档化用法都仅限于静态构造函数,如 Limit::perMinute
和 Limit::perSecond
。但是,如果手动实例化此类,则应更新应用,以便为类的构造函数提供秒:
new Limit($key, $attempts, 2 * 60);
Limit
类的 decayMinutes
属性已被重命名为 decaySeconds
并用秒替代了分钟。
Illuminate\Queue\Middleware\ThrottlesExceptions
和 Illuminate\Queue\Middleware\ThrottlesExceptionsWithRedis
类的构造函数现在接受秒而非分钟
new ThrottlesExceptions($attempts, 2 * 60);
new ThrottlesExceptionsWithRedis($attempts, 2 * 60);
Cashier Stripe
Cashier Stripe 更新
影响可能性:高
Laravel 11 不再支持 Cashier Stripe 14.x。因此,你应该在 composer.json
文件中将应用的 Laravel Cashier Stripe 依赖更新到 ^15.0
。
Cashier Stripe 15.0 不再从它自己的迁移目录中自动加载迁移。因此,你应该运行如下命令发布 Cashier Stripe 的迁移:
php artisan vendor:publish --tag=cashier-migrations
Cashier Stripe 的其他破坏性更新请查看完整的 Cashier Stripe 升级指南。
Spark (Stripe)
Spark Stripe 更新
影响可能性:高
Laravel 11 不再支持 Laravel Spark Stripe 4.x。 因此,你应该在 composer.json
文件中将应用的 Laravel Spark Stripe 依赖更新到 ^5.0
。
Spark Stripe 5.0 不再从它自己的迁移目录中自动加载迁移。因此,你应该运行如下命令将 Spark Stripe 的迁移发布到你的应用中:
php artisan vendor:publish --tag=spark-migrations
Spark Stripe 的其他破坏性更新请查看完整的 Spark Stripe 升级指南。
Passport
更新 Passport
影响可能性:高
Laravel 11 不再支持 Laravel Passport 11.x。 因此,你应该在 composer.json
文件中将应用的 Laravel Passport 依赖更新到 ^12.0
。
Passport 12.0 不再从它自己的迁移目录中自动加载迁移。因此,你应该运行如下命令将 Passport 的迁移发布到你的应用中:
php artisan vendor:publish --tag=passport-migrations
此外,密码的授权类型默认是禁用的。你可以在应用 AppServiceProvider
的 boot
方法中调用 enablePasswordGrant
方法对其进行启用:
public function boot(): void
{
Passport::enablePasswordGrant();
}
Sanctum
更新 Sanctum
影响可能性:高
Laravel 11 不再支持 Laravel Sanctum 3.x。 因此,你应该在 composer.json
文件中将应用的 Laravel Sanctum 依赖更新到 ^4.0
。
Sanctum 4.0 不再从它自己的迁移目录中自动加载迁移。因此,你应该运行如下命令将 Sanctum 的迁移发布到你的应用中:
php artisan vendor:publish --tag=sanctum-migrations
然后,在应用的 config/sanctum.php
配置文件中,你应该将 authenticate_session
、encrypt_cookies
和 validate_csrf_token
中间件更新如下:
'middleware' => [
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
],
Telescope
更新 Telescope
影响可能性:高
Laravel 11 不再支持 Laravel Telescope 4.x。 因此,你应该在 composer.json
文件中将应用的 Laravel Telescope 依赖更新到 ^5.0
。
Telescope 5.0 不再从它自己的迁移目录中自动加载迁移。因此,你应该运行如下命令将 Telescope 的迁移发布到你的应用中:
php artisan vendor:publish --tag=telescope-migrations
Spatie Once 包
影响可能性:中等
Laravel 11 现在提供了自己的 once
函数,以确保给定的闭包只执行一次。因此,如果你的应用依赖 spatie/one
包,则应将其从应用的 composer.json
文件中删除,以避免冲突。
原文地址:https://laravel.com/docs/11.x/upgrade