高影响变化
中影响变化
低影响变化
从 10.x 升级到 11.0
预计升级时间:15 分钟
[!NOTE]
我们尽力记录每一个可能的破坏性变化。由于其中一些破坏性变化仅在框架的不常见部分,因此这些变化中只有一部分可能实际影响您的应用程序。想节省时间吗?您可以使用 Laravel Shift (opens in a new tab) 来帮助自动化您的应用程序升级。
更新依赖项
影响可能性:高
PHP 8.2.0 要求
Laravel 现在需要 PHP 8.2.0 或更高版本。
curl 7.34.0 要求
Laravel 的 HTTP 客户端现在需要 curl 7.34.0 或更高版本。
Composer 依赖项
您应该在应用程序的 composer.json
文件中更新以下依赖项:
laravel/framework
到^11.0
nunomaduro/collision
到^8.1
laravel/breeze
到^2.0
(如果已安装)laravel/cashier
到^15.0
(如果已安装)laravel/dusk
到^8.0
(如果已安装)laravel/jetstream
到^5.0
(如果已安装)laravel/octane
到^2.3
(如果已安装)laravel/passport
到^12.0
(如果已安装)laravel/sanctum
到^4.0
(如果已安装)laravel/scout
到^10.0
(如果已安装)laravel/spark-stripe
到^5.0
(如果已安装)laravel/telescope
到^5.0
(如果已安装)livewire/livewire
到^3.4
(如果已安装)inertiajs/inertia-laravel
到^1.0
(如果已安装)
如果您的应用程序正在使用 Laravel Cashier Stripe、Passport、Sanctum、Spark Stripe 或 Telescope,您需要将它们的迁移发布到您的应用程序中。Cashier 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 安装程序,您应该通过 Composer 更新安装程序:
composer global require laravel/installer:^5.6
最后,如果您之前将 doctrine/dbal
Composer 依赖项添加到您的应用程序中,您可以将其删除,因为 Laravel 不再依赖于此包。
应用结构
Laravel 11 引入了一个新的默认应用结构,默认文件更少。也就是说,新的 Laravel 应用程序包含更少的服务提供者、中间件和配置文件。
然而,我们 不建议 将 Laravel 10 应用程序升级到 Laravel 11 时尝试迁移其应用结构,因为 Laravel 11 已经经过精心调整,也支持 Laravel 10 的应用结构。
认证
密码重新哈希
如果自上次哈希密码以来,您的哈希算法的“工作因子”已更新,Laravel 11 将在认证过程中自动重新哈希您的用户密码。
通常,这不应该中断您的应用程序;但是,您可以通过将 rehash_on_login
选项添加到应用程序的 config/hashing.php
配置文件中来禁用此行为:
'rehash_on_login' => false,
UserProvider
契约
影响可能性:低
Illuminate\Contracts\Auth\UserProvider
契约已接收一个新的 rehashPasswordIfRequired
方法。此方法负责在应用程序的哈希算法工作因子发生变化时,重新哈希并将用户的密码存储在存储中。
如果您的应用程序或包定义了一个实现此接口的类,则应在您的实现中添加新的 rehashPasswordIfRequired
方法。在 Illuminate\Auth\EloquentUserProvider
类中可以找到参考实现:
public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false);
Authenticatable
契约
影响可能性:低
Illuminate\Contracts\Auth\Authenticatable
契约已接收一个新的 getAuthPasswordName
方法。此方法负责返回您的可认证实体的密码列的名称。
如果您的应用程序或包定义了一个实现此接口的类,则应在您的实现中添加新的 getAuthPasswordName
方法:
public function getAuthPasswordName()
{
return 'password';
}
Laravel 附带的默认 User
模型会自动接收此方法,因为该方法包含在 Illuminate\Auth\Authenticatable
特征中。
AuthenticationException
类
影响可能性:极低
Illuminate\Auth\AuthenticationException
类的 redirectTo
方法现在需要一个 Illuminate\Http\Request
实例作为其第一个参数。如果您手动捕获此异常并调用 redirectTo
方法,则应相应地更新您的代码:
if ($e instanceof AuthenticationException) {
$path = $e->redirectTo($request);
}
缓存
缓存键前缀
影响可能性:极低
以前,如果为 DynamoDB、Memcached 或 Redis 缓存存储定义了缓存键前缀,Laravel 会将 :
附加到前缀上。在 Laravel 11 中,缓存键前缀不会收到 :
后缀。如果您想保持以前的前缀行为,可以手动将 :
后缀添加到您的缓存键前缀中。
集合
Enumerable
契约
影响可能性:低
Illuminate\Support\Enumerable
契约的 dump
方法已更新,以接受可变参数 ...$args
。如果您正在实现此接口,则应相应地更新您的实现:
public function dump(...$args);
数据库
SQLite 3.26.0 +
影响可能性:高
如果您的应用程序正在使用 SQLite 数据库,则需要 SQLite 3.26.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
方法不会更改列的索引。因此,在修改列时,可以使用索引修饰符来显式地添加或删除索引:
// 添加索引...
$table->bigIncrements('id')->primary()->change();
// 删除索引...
$table->char('postal_code', 10)->unique(false)->change();
如果您不想更新应用程序中所有现有的“更改”迁移以保留列的现有属性,可以简单地压缩迁移:
php artisan schema:dump
一旦迁移被压缩,Laravel 将在运行任何待处理的迁移之前,使用应用程序的模式文件“迁移”数据库。
浮点类型
影响可能性:高
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
方法已被删除,因为 MySQL 已弃用这些列类型的无符号修饰符,并且在其他数据库系统上从未标准化。但是,如果您希望继续为这些列类型使用已弃用的无符号属性,可以将unsigned
方法链接到列的定义上:
$table->decimal('amount', total: 8, places: 2)->unsigned();
$table->double('amount')->unsigned();
$table->float('amount', precision: 53)->unsigned();
专用 MariaDB 驱动
影响可能性:非常低
当连接到 MariaDB 数据库时,Laravel 11 不再总是使用 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
模式构建器方法创建原生 UUID 列,而不是char(36)
列。
如果您现有的迁移使用了uuid
模式构建器方法,并且您选择使用新的mariadb
数据库驱动,您应该将迁移中对uuid
方法的调用更新为char
,以避免破坏更改或意外行为:
Schema::table('users', function (Blueprint $table) {
$table->char('uuid', 36);
//...
});
空间类型
影响可能性:低
数据库迁移的空间列类型已被重写,以在所有数据库中保持一致。因此,您可以从迁移中删除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 不再依赖此包,并且对于正确创建和更改以前需要自定义类型的各种列类型,不再需要注册自定义 Doctrine 类型:
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()
方法
此外,在应用程序的database
配置文件中通过dbal.types
注册自定义 Doctrine 类型不再需要。
如果您以前使用 Doctrine DBAL 来检查您的数据库及其相关表,您可以使用 Laravel 的新原生模式方法(Schema::getTables()
、Schema::getColumns()
、Schema::getIndexes()
、Schema::getForeignKeys()
等)代替。
已弃用的模式方法
影响可能性:非常低
已弃用的、基于 Doctrine 的Schema::getAllTables()
、Schema::getAllViews()
和Schema::getAllTypes()
方法已被删除,取而代之的是新的 Laravel 原生Schema::getTables()
、Schema::getViews()
和Schema::getTypes()
方法。
当使用 PostgreSQL 和 SQL Server 时,新的模式方法都不会接受三部分引用(例如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);
日期
Carbon 3
影响可能性:中等
Laravel 11 同时支持 Carbon 2 和 Carbon 3。Carbon 是一个日期操作库,在 Laravel 及整个生态系统的包中被广泛使用。如果升级到 Carbon 3,请注意,diffIn*
方法现在返回浮点数,并可能返回负值以指示时间方向,这与 Carbon 2 有很大的不同。查看 Carbon 的变更日志 (opens in a new tab),以获取有关如何处理这些及其他变更的详细信息。
邮件
Mailer
契约
影响可能性:非常低
Illuminate\Contracts\Mail\Mailer
契约新增了一个sendNow
方法。如果您的应用程序或包手动实现了此契约,您应该在实现中添加新的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();
数据库事务中的同步任务
影响可能性:非常低
以前,同步任务(使用sync
队列驱动程序的任务)会立即执行,无论队列连接的after_commit
配置选项是否设置为true
,或者是否在任务上调用了afterCommit
方法。
在 Laravel 11 中,同步队列任务现在将尊重队列连接或任务的“提交后”配置。
速率限制
每秒速率限制
影响可能性:中等
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 升级指南 (opens in a new tab)以获取其他破坏性更改。
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 升级指南 (opens in a new tab)以获取其他破坏性更改。
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/once
包,您应该从应用程序的composer.json
文件中删除它,以避免冲突。
杂项
我们还鼓励您查看laravel/laravel
GitHub 仓库 (opens in a new tab)中的更改。虽然这些更改中的许多不是必需的,但您可能希望将这些文件与您的应用程序保持同步。本升级指南将涵盖其中的一些更改,但其他更改,如对配置文件或注释的更改,将不会涵盖。您可以使用GitHub 比较工具 (opens in a new tab)轻松查看更改,并选择对您重要的更新。