跳至内容

升级指南

重大更改

中等影响的更改

低影响的更改

从 10.x 升级到 11.0

估计升级时间:15 分钟

lightbulb

我们尝试记录所有可能的重大更改。由于其中一些重大更改位于框架的模糊部分,因此只有部分更改会实际影响你的应用程序。想要节省时间?可以使用 Laravel Shift 帮助自动执行应用程序升级。

更新依赖项

影响可能性:高

需要 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 会在身份验证期间自动重新哈希用户的密码。

通常,这不会中断你的应用程序;但是,如果你的 User 模型的“password”字段的名称与 password 不同,则应该通过模型的 authPasswordName 属性指定字段的名称

protected $authPasswordName = 'custom_password_field';

或者,你也可以通过将 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 方法冲突。

修改列

影响可能性:高

在修改列时,你现在必须显式包含要在列定义更改后保留的所有修饰符。任何缺少的属性都会被删除。例如,要保留 unsigneddefaultcomment 属性,你必须在更改列时显式调用每个修饰符,即使这些属性已由之前的迁移分配给列。

例如,假设你有一个迁移,它使用 unsigneddefaultcomment 属性创建 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 中,此迁移会保留列上的 unsigneddefaultcomment 属性。但是,在 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();

如果你不想更新应用程序中所有现有的“change”迁移以保留列的现有属性,你只需 压缩你的迁移

php artisan schema:dump

压缩迁移后,Laravel 将使用应用程序的模式文件“迁移”数据库,然后再运行任何待处理的迁移。

浮点数类型

影响可能性:高

doublefloat 迁移列类型已重写,使其在所有数据库中保持一致。

double 列类型现在创建一个等效的 DOUBLE 列,没有总位数和小数位数(小数点后的位数),这是标准的 SQL 语法。因此,您可以删除 $total$places 的参数

$table->double('amount');

float 列类型现在创建一个等效的 FLOAT 列,没有总位数和小数位数(小数点后的位数),但有一个可选的 $precision 规范,以确定存储大小为 4 字节单精度列或 8 字节双精度列。因此,您可以删除 $total$places 的参数,并根据数据库文档将可选的 $precision 指定为所需的值

$table->float('amount', precision: 53);

unsignedDecimalunsignedDoubleunsignedFloat 方法已被删除,因为这些列类型的无符号修饰符已在 MySQL 中被弃用,并且从未在其他数据库系统上标准化。但是,如果您希望继续使用这些列类型的弃用无符号属性,您可以将 unsigned 方法链接到列的定义中

$table->decimal('amount', total: 8, places: 2)->unsigned();
$table->double('amount')->unsigned();
$table->float('amount', precision: 53)->unsigned();

专用的 MariaDB 驱动程序

影响可能性:非常低

Laravel 11 添加了一个专用的 MariaDB 数据库驱动程序,而不是始终在连接到 MariaDB 数据库时使用 MySQL 驱动程序。

如果您的应用程序连接到 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);
 
// ...
});

空间类型

影响可能性:低

数据库迁移的空间列类型已被重写,以确保在所有数据库中保持一致。因此,您可以从迁移中删除 pointlineStringpolygongeometryCollectionmultiPointmultiLineStringmultiPolygonmultiPolygonZ 方法,而是使用 geometrygeography 方法

$table->geometry('shapes');
$table->geography('coordinates');

为了明确限制 MySQL、MariaDB 和 PostgreSQL 中存储在列中的值的类型或空间参考系统标识符,您可以将 subtypesrid 传递给该方法

$table->geometry('dimension', subtype: 'polygon', srid: 0);
$table->geography('latitude', subtype: 'point', srid: 4326);

PostgreSQL 语法的 isGeometryprojection 列修饰符已被相应删除。

删除 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() 方法

此外,不再需要在应用程序的 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');

架构构建器 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 的 更改日志文档,以获取有关如何处理这些更改和其他更改的详细信息。

邮件

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::perMinuteLimit::perSecond。但是,如果您正在手动实例化此类,则应更新您的应用程序以将秒提供给类的构造函数

new Limit($key, $attempts, 2 * 60);

Limit 类的 decayMinutes 属性已重命名为 decaySeconds,现在包含秒而不是分钟。

Illuminate\Queue\Middleware\ThrottlesExceptionsIlluminate\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 升级指南

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 升级指南

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

此外,密码授权类型默认情况下处于禁用状态。您可以在应用程序的 AppServiceProviderboot 方法中调用 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_sessionencrypt_cookiesvalidate_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 存储库 中的更改。虽然许多这些更改不是必需的,但您可能希望使这些文件与您的应用程序保持同步。其中一些更改将在本升级指南中介绍,但其他更改,例如对配置文件或注释的更改,将不会介绍。您可以使用 GitHub 比较工具 轻松查看更改,并选择哪些更新对您很重要。