即将到来的 Laravel 9 一览
发布于 作者: Eric L. Barnes
Laravel v9 是 Laravel 的下一个主要版本,并于 2022 年 2 月 8 日 发布。在这篇文章中,我们想要概述此版本中的所有新功能和更改。
Laravel 9 发布日期更改
Laravel v9 原定于今年 9 月左右发布,但 Laravel 团队决定将该版本推迟至 2022 年 2 月
Laravel 使用了各种社区驱动的软件包以及九个 Symfony 组件为框架内的多种功能提供支持。Symfony 6.0 预计将于 11 月发布。出于该原因,我们选择推迟 Laravel 9.0 的发布至 2022 年。通过推迟发布,我们可以在无需等到 2022 年 9 月即可对底层 Symfony 组件升级至 Symfony 6.0。此外,这会让我们在未来版本中拥有更好的定位,因为我们的年度版本将始终在 Symfony 版本发布后两个月发布。
这也将推迟未来主要版本的发布,以下是即将推出的时间表
- Laravel 9:2022 年 2 月 8 日
- Laravel 10:2023 年 2 月 7 日
PHP 8 是 Laravel 9 中的最低版本
由于 Laravel 9 需要 Symfony 6.0,并且它对 PHP 8 有最低要求,这意味着 Laravel 9 将带有此相同的限制。
routes:list 的新设计
routes:list
命令已经包含在 Laravel 中很长时间了,现在出现的一个问题是,如果您定义了庞大而复杂的路由,那么在控制台中查看这些路由可能变得凌乱。多亏 Nuno Maduro 的拉取请求,这一问题正在得到改造。
新的测试覆盖选项
新的 artisan test --coverage
选项将直接在终端上显示测试覆盖率。它还包括一个 --min
选项,您可以使用此选项为测试覆盖率指定最小阈值强制执行。
匿名存根迁移
今年早些时候,Laravel 8.37 推出了一个名为匿名迁移的新功能,该功能可防止迁移类名称冲突。
use Illuminate\Database\Migrations\Migration;use Illuminate\Database\Schema\Blueprint;use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('people', function (Blueprint $table) { $table->string('first_name')->nullable(); }); }};
当 Laravel 9 启动时,这将是您运行 php artisan make:migration
时的默认设置
新的查询构建器接口
多亏了 Chris Morrell,Laravel 9 将采用新的查询构建器接口,您可以在合并的 PR中查看所有详细信息。
对于依赖类型提示进行静态分析、重构或在 IDE 中进行代码完成的开发人员而言,
Query\Builder
、Eloquent\Builder
和Eloquent\Relation
之间缺少共享接口或继承关系可能非常棘手
return Model::query() ->whereNotExists(function($query) { // $query is a Query\Builder }) ->whereHas('relation', function($query) { // $query is an Eloquent\Builder }) ->with('relation', function($query) { // $query is an Eloquent\Relation });
此功能新增了一个 Illuminate\Contracts\Database\QueryBuilder
接口,以及一个 Illuminate\Database\Eloquent\Concerns\DecoratesQueryBuilder
特性,其使用此接口代替现有的 __call
实现。
PHP 8 字符串函数
由于 PHP 8 将是最低版本,Tom Schlick 提交了一个 PR 以便在 \Illuminate\Support\Str
类中内部使用 str_contains()
、str_starts_with()
和 str_ends_with()
函数。
从 SwiftMailer 到 Symfony Mailer
Symfony Mailer 支持由 Dries Vints、James Brooks 和 Julius Kiekbusch 提供
以前版本的 Laravel 使用 Swift Mailer 库来发送外发电子邮件。然而,该库不再受维护并且已由 Symfony Mailer 取代。
请查看 升级指南 以了解有关如何确保您的应用程序与 Symfony Mailer 兼容的更多信息。
Flysystem 3.x
Flysystem 3.x 支持由 Dries Vints 提供.
Laravel 9.x 将我们上游的 Flysystem 依赖项升级到 Flysystem 3.x。Flysystem 驱动了 Storage
界面提供的全部文件系统交互操作。
改进的 Eloquent 存取器/变异器
改进的 Eloquent 存取器/变异器由 Taylor Otwell 提供.
Laravel 9.x 提供了一种定义 Eloquent 存取器和变异器 的新方式。在以前的 Laravel 版本中,定义存取器和变异器的唯一方法是通过在您的模型上定义带前缀的方法,如下所示
public function getNameAttribute($value){ return strtoupper($value);} public function setNameAttribute($value){ $this->attributes['name'] = $value;}
但是,在 Laravel 9.x 中,您可以使用单个非前缀方法定义存取器和变异器,方法是类型提示返回类型为 Illuminate\Database\Eloquent\Casts\Attribute
use Illuminate\Database\Eloquent\Casts\Attribute; public function name(): Attribute{ return new Attribute( get: fn ($value) => strtoupper($value), set: fn ($value) => $value, );}
此外,这种新的定义存取器的方法将缓存属性返回的对象值,就像 自定义类型转换类
use App\Support\Address;use Illuminate\Database\Eloquent\Casts\Attribute; public function address(): Attribute{ return new Attribute( get: fn ($value, $attributes) => new Address( $attributes['address_line_one'], $attributes['address_line_two'], ), set: fn (Address $value) => [ 'address_line_one' => $value->lineOne, 'address_line_two' => $value->lineTwo, ], );}
使用枚举的隐式路由绑定
隐式枚举绑定由 Nuno Maduro 提供.
PHP 8.1 引入了对 枚举 的支持。Laravel 9.x 引入了在路由定义中对枚举进行类型提示的功能,如果该路由段是 URI 中的有效枚举值,Laravel 才会调用该路由。否则,将自动返回 HTTP 404 响应。例如,给定以下枚举
enum Category: string{ case Fruits = 'fruits'; case People = 'people';}
您可以定义一条路由,该路由仅在 {category}
路由段为 fruits
或 people
时才会被调用。否则,将返回 HTTP 404 响应
Route::get('/categories/{category}', function (Category $category) { return $category->value;});
控制器路由组
路由组改进由 Luke Downing 贡献.
现在,您可以使用 controller
方法为该组中的所有路由定义通用控制器。然后,在定义路由时,您只需提供它们调用的控制器方法即可
use App\Http\Controllers\OrderController; Route::controller(OrderController::class)->group(function () { Route::get('/orders/{id}', 'show'); Route::post('/orders', 'store');});
枚举 Eloquent 属性类型转换
{note} 枚举类型转换仅适用于 PHP 8.1 及更高版本。
枚举类型转换由 Mohamed Said 贡献.
Eloquent 现在允许您将属性值转换为 PHP 枚举。要实现此目的,您可以在模型的 $casts
属性数组中指定要转换的属性和枚举
use App\Enums\ServerStatus; /** * The attributes that should be cast. * * @var array */protected $casts = [ 'status' => ServerStatus::class,];
在模型上定义类型转换后,与属性交互时,指定的属性将自动转换为枚举,反之亦然
if ($server->status == ServerStatus::provisioned) { $server->status = ServerStatus::ready; $server->save();}
强制范围绑定
强制范围绑定由 Claudio Dekker 贡献.
在之前的 Laravel 版本中,您可能希望在路由定义中限定第二个 Eloquent 模型,使其必须是前一个 Eloquent 模型的子模型。例如,考虑这个路由定义,它通过特定的用户来按 slug 检索一篇博文
use App\Models\Post;use App\Models\User; Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) { return $post;});
使用自定义键隐式绑定作为嵌套路由参数时,Laravel 会自动将查询限定为使用惯例从其父模型中检索嵌套模型以猜测父模型上的关系名称。但是,此行为以前仅在为子路由绑定使用自定义键时由 Laravel 支持。
但是,在 Laravel 9.x 中,现在您可以指示 Laravel 在未提供自定义键时限定“子”绑定。为此,您可以在定义路由时调用 scopeBindings
方法
use App\Models\Post;use App\Models\User; Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) { return $post;})->scopeBindings();
或者,您可以指示一组完整的路由定义使用限定范围
Route::scopeBindings()->group(function () { Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) { return $post; });});
Laravel Breeze API & Next.js
Laravel Breeze API 脚手架和 Next.js 初学者工具包由 Taylor Otwell 和 Miguel Piedrafita 共同贡献.
Laravel Breeze 初学者工具包新增了“API”脚手架模式和免费的 Next.js 前端实现。可以利用此初学者工具包脚手架作为你的 Laravel 应用程序的切入点,用作后端,通过 Laravel Sanctum 验证用于 JavaScript 前端的 API。
Laravel Scout 数据库引擎
Laravel Scout 数据库引擎由 Taylor Otwell 和 Dries Vints 共同贡献.
如果你的应用程序与中小规模数据库交互,或者工作负载较轻,现在你可以使用 Scout 的“database”引擎,而无需使用 Algolia 或 MeiliSerach 等专门的搜索服务。该数据库引擎在从现有数据库过滤结果以确定适用于查询的搜索结果时,将使用“where like”子句和全文索引。
全文索引/Where 子句
全文索引和“where”子句由 Taylor Otwell 和 Dries Vints 共同贡献.
现在在使用 MySQL 或 PostgreSQL 时,可以将 fullText
方法添加到列定义中以生成全文索引
$table->text('bio')->fullText();
此外,whereFullText
和 orWhereFullText
方法可用于为具有全文索引的列向查询添加全文“where”子句。Laravel 将针对基础数据库系统将这些方法转换成适当的 SQL。例如,将为使用 MySQL 的应用程序生成 MATCH AGAINST
子句
$users = DB::table('users') ->whereFullText('bio', 'web developer') ->get();
渲染内嵌 Blade 模板
有时,你可能需要将原始 Blade 模板字符串转换为有效的 HTML。你可以使用 Blade
外观提供的 render
方法来完成此操作。render
方法接受 Blade 模板字符串和一个向模板提供的可选数据数组
use Illuminate\Support\Facades\Blade; return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);
Soketi Echo Server
Soketi Echo 服务器由 Alex Renoki 开发.
虽然并非 Laravel 9.x 独有,但 Laravel 最近为 Soketi 提供了文档说明,Soketi 是一个 Laravel Echo 兼容的 Web Socket 服务器,为 Node.js 编写。对于更喜欢管理自己 Web Socket 服务器的应用程序而言,Soketi 提供了一个出色的开源选项,可以替代 Pusher 和 Ably。
Bootstrap 5 分页视图
Laravel 现在包括使用 Bootstrap 5 构建的分页视图。要使用这些视图,而不是默认的 Tailwind 视图,您可以在 `App\Providers\AppServiceProvider` 类的 `boot` 方法中调用分页器的 `useBootstrapFive` 方法
use Illuminate\Pagination\Paginator; /** * Bootstrap any application services. * * @return void */public function boot(){ Paginator::useBootstrapFive();}
改进的 Ignition 异常页面
Spatie 创建的开源异常调试页面 Ignition 已从头进行了重新设计。Laravel 9.x 附带全新的、改进的 Ignition,包括浅色/深色主题、可自定义的“在编辑器中打开”功能等等。
新的帮助器
Laravel 9.x 引入了两个新的、可方便使用的帮助器函数,您可以在自己的应用程序中使用它们。
str
str
函数为给定的字符串返回新的 Illuminate\Support\Stringable
实例。此函数与 Str::of
方法等效
$string = str('Taylor')->append(' Otwell'); // 'Taylor Otwell'
如果未向 str
函数提供参数,则该函数返回一个 Illuminate\Support\Str
实例
$snake = str()->snake('LaravelFramework'); // 'laravel_framework'
to_route
to_route
函数为给定的命名路由生成一个重定向 HTTP 响应,为从您的路由和控制器重定向到命名路由提供了一种表达方式
return to_route('users.show', ['user' => 1]);
必要时,您可以将应分配给重定向操作的 HTTP 状态代码以及任何其他响应标头作为第三个和第四个参数传递给 to_route 方法
return to_route('users.show', ['user' => 1], 302, ['X-Framework' => 'Laravel']);
server.php 文件可以删除
这是一个小功能,但您现在可以从您的项目中删除 server.php
文件,它将包含在框架中。此文件仅用于 php artisan serve
。
更多信息...
Laravel 9 还有几个月才会推出,届时将会有更多新功能和公告发布。我们会在这些功能和公告发布时更新此博文。您还可以查看 官方发行页面。