升级指南
高影响更改
中等影响更改
低影响更改
从 10.x 升级到 11.0
预计升级时间:15 分钟
我们尝试记录每个可能的中断性更改。由于其中一些中断性更改发生在框架中不常用的部分,因此只有一部分更改可能会实际影响您的应用程序。想节省时间吗?您可以使用 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-migrationsphp artisan vendor:publish --tag=passport-migrationsphp artisan vendor:publish --tag=sanctum-migrationsphp artisan vendor:publish --tag=spark-migrationsphp 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';
或者,您可以通过向应用程序的 config/hashing.php 配置文件添加 rehash_on_login 选项来禁用密码重新哈希
'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 trait 中。
AuthenticationException 类
影响可能性:非常低
Illuminate\Auth\AuthenticationException 类的 redirectTo 方法现在需要一个 Illuminate\Http\Request 实例作为其第一个参数。如果您正在手动捕获此异常并调用 redirectTo 方法,则应相应地更新您的代码
if ($e instanceof AuthenticationException) { $path = $e->redirectTo($request);}
注册时的电子邮件验证通知
影响可能性:非常低
如果你的应用程序的 EventServiceProvider 尚未注册 SendEmailVerificationNotification 监听器,那么现在它会自动为 Registered 事件注册。如果你的应用程序的 EventServiceProvider 没有注册此监听器,并且你不希望 Laravel 自动为你注册它,你应该在你的应用程序的 EventServiceProvider 中定义一个空的 configureEmailVerification 方法。
protected function configureEmailVerification(){ // ...}
缓存
缓存键前缀
影响可能性:非常低
之前,如果为 DynamoDB、Memcached 或 Redis 缓存存储定义了缓存键前缀,Laravel 会在 prefix 后追加一个 :。在 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 方法不会更改列的索引。因此,你可以在修改列时使用索引修饰符来显式添加或删除索引
// 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 将在运行任何挂起的迁移之前,使用你的应用程序的模式文件“迁移”数据库。
浮点类型
影响可能性:高
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 的专用数据库驱动程序,而不是在连接 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); // ...});
空间类型
影响可能性:低
数据库迁移的空间列类型已被重写,以在所有数据库中保持一致。因此,你可以从迁移中删除 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');
模式构建器 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 应用程序中,providers 数组不存在于 config/app.php 配置文件中。
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 升级指南,了解其他破坏性更改。
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
此外,密码授权类型默认情况下是禁用的。您可以通过在应用程序的 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 仓库 中的更改。 虽然这些更改中的许多不是必需的,但您可能希望使这些文件与您的应用程序保持同步。 其中一些更改将在本升级指南中介绍,但其他更改(例如对配置文件或注释的更改)将不会介绍。 您可以使用 GitHub 比较工具 轻松查看更改,并选择对您重要的更新。