Skip to content

发布说明

版本方案

Laravel 及其其他第一方包遵循 语义版本控制。主要框架版本每年发布一次(大约在二月),而次要和补丁版本可能每周发布一次。次要和补丁版本绝不应包含破坏性更改。

在从您的应用程序或包引用 Laravel 框架或其组件时,您应始终使用版本约束,例如 ^9.0,因为 Laravel 的主要版本确实包含破坏性更改。然而,我们努力确保您可以在一天或更短的时间内更新到新的主要版本。

命名参数

命名参数不在 Laravel 的向后兼容性指南中。我们可能会在必要时重命名函数参数,以改善 Laravel 代码库。因此,在调用 Laravel 方法时使用命名参数应谨慎,并理解参数名称可能在未来发生变化。

支持政策

对于所有 Laravel 版本,错误修复提供 18 个月,安全修复提供 2 年。对于所有其他库,包括 Lumen,只有最新的主要版本会收到错误修复。此外,请查看 Laravel 支持的数据库版本

版本PHP (*)发布错误修复截止安全修复截止
6 (LTS)7.2 - 8.02019年9月3日2022年1月25日2022年9月6日
77.2 - 8.02020年3月3日2020年10月6日2021年3月3日
87.3 - 8.12020年9月8日2022年7月26日2023年1月24日
98.0 - 8.22022年2月8日2023年8月8日2024年2月6日
108.1 - 8.32023年2月14日2024年8月6日2025年2月4日
生命周期结束
仅安全修复

(*) 支持的 PHP 版本

Laravel 9

如您所知,Laravel 在发布 Laravel 8 时过渡到年度发布。之前,主要版本每 6 个月发布一次。这一过渡旨在减轻社区的维护负担,并挑战我们的开发团队在不引入破坏性更改的情况下发布出色、强大的新功能。因此,我们在不破坏向后兼容性的情况下向 Laravel 8 提供了一系列强大的功能,例如并行测试支持、改进的 Breeze 启动包、HTTP 客户端改进,甚至新的 Eloquent 关系类型,如“拥有多个中的一个”。

因此,我们在当前版本中承诺发布出色的新功能,未来的“主要”版本可能主要用于“维护”任务,例如升级上游依赖项,这可以在这些发布说明中看到。

Laravel 9 继续在 Laravel 8.x 中所做的改进,推出对 Symfony 6.0 组件、Symfony Mailer、Flysystem 3.0、改进的 route:list 输出、Laravel Scout 数据库驱动、新的 Eloquent 访问器/修改器语法、通过枚举的隐式路由绑定以及各种其他错误修复和可用性改进的支持。

PHP 8.0

Laravel 9.x 需要最低 PHP 版本为 8.0。

Symfony Mailer

Symfony Mailer 支持由 Dries VintsJames BrooksJulius 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 facade 提供的所有文件系统交互提供支持。

请查看 升级指南,了解如何确保您的应用程序与 Flysystem 3.x 兼容。

改进的 Eloquent 访问器/修改器

改进的 Eloquent 访问器/修改器由 Taylor Otwell 贡献。

Laravel 9.x 提供了一种新的方式来定义 Eloquent 访问器和修改器。在 Laravel 的早期版本中,定义访问器和修改器的唯一方法是通过在模型上定义带前缀的方法,如下所示:

php
public function getNameAttribute($value)
{
    return strtoupper($value);
}

public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}

然而,在 Laravel 9.x 中,您可以通过类型提示返回类型为 Illuminate\Database\Eloquent\Casts\Attribute 的单个非前缀方法来定义访问器和修改器:

php
use Illuminate\Database\Eloquent\Casts\Attribute;

public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}

此外,这种定义访问器的新方法将缓存通过属性返回的对象值,就像 自定义转换类 一样:

php
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,
        ],
    );
}

枚举 Eloquent 属性转换

exclamation

枚举转换仅适用于 PHP 8.1 及以上版本。

枚举转换由 Mohamed Said 贡献。

Eloquent 现在允许您将属性值转换为 PHP "后备" 枚举。要实现此目的,您可以在模型的 $casts 属性数组中指定要转换的属性和枚举:

php
use App\Enums\ServerStatus;

/**
 * 应该转换的属性。
 *
 * @var array
 */
protected $casts = [
    'status' => ServerStatus::class,
];

一旦您在模型上定义了转换,指定的属性将在您与该属性交互时自动转换为枚举并从枚举转换:

php
if ($server->status == ServerStatus::Provisioned) {
    $server->status = ServerStatus::Ready;

    $server->save();
}

使用枚举的隐式路由绑定

隐式枚举绑定由 Nuno Maduro 贡献。

PHP 8.1 引入了对 枚举 的支持。Laravel 9.x 引入了在路由定义中类型提示枚举的能力,只有当该路由段是 URI 中有效的枚举值时,Laravel 才会调用该路由。否则,将自动返回 HTTP 404 响应。例如,给定以下枚举:

php
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}

您可以定义一个路由,只有当 {category} 路由段为 fruitspeople 时才会被调用。否则,将自动返回 HTTP 404 响应:

php
Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});

强制路由绑定的作用域

强制作用域绑定由 Claudio Dekker 贡献。

在 Laravel 的早期版本中,您可能希望在路由定义中对第二个 Eloquent 模型进行作用域限制,以便它必须是前一个 Eloquent 模型的子项。例如,考虑以下路由定义,它根据 slug 检索特定用户的博客文章:

php
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 方法:

php
use App\Models\Post;
use App\Models\User;

Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
    return $post;
})->scopeBindings();

或者,您可以指示一组路由定义使用作用域绑定:

php
Route::scopeBindings()->group(function () {
    Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
        return $post;
    });
});

控制器路由组

路由组改进由 Luke Downing 贡献。

您现在可以使用 controller 方法定义组内所有路由的公共控制器。然后,在定义路由时,您只需提供它们调用的控制器方法:

php
use App\Http\Controllers\OrderController;

Route::controller(OrderController::class)->group(function () {
    Route::get('/orders/{id}', 'show');
    Route::post('/orders', 'store');
});

全文索引/条件

全文索引和“条件”由 Taylor OtwellDries Vints 贡献。

在使用 MySQL 或 PostgreSQL 时,可以将 fullText 方法添加到列定义中以生成全文索引:

php
$table->text('bio')->fullText();

此外,可以使用 whereFullTextorWhereFullText 方法为具有 全文索引 的列添加全文“条件”。这些方法将被转换为适合底层数据库系统的 SQL。例如,对于使用 MySQL 的应用程序,将生成 MATCH AGAINST 子句:

php
$users = DB::table('users')
           ->whereFullText('bio', 'web developer')
           ->get();

Laravel Scout 数据库引擎

Laravel Scout 数据库引擎由 Taylor OtwellDries Vints 贡献。

如果您的应用程序与小型到中型数据库交互或工作负载较轻,您现在可以使用 Scout 的“数据库”引擎,而不是像 Algolia 或 MeiliSearch 这样的专用搜索服务。数据库引擎将在从现有数据库中过滤结果时使用“like”条件和全文索引,以确定查询的适用搜索结果。

要了解有关 Scout 数据库引擎的更多信息,请查阅 Scout 文档

渲染内联 Blade 模板

渲染内联 Blade 模板由 Jason Beggs 贡献。渲染内联 Blade 组件由 Toby Zerner 贡献。

有时,您可能需要将原始 Blade 模板字符串转换为有效的 HTML。您可以使用 Blade facade 提供的 render 方法来实现。render 方法接受 Blade 模板字符串和可选的数据数组,以提供给模板:

php
use Illuminate\Support\Facades\Blade;

return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);

同样,renderComponent 方法可用于通过将组件实例传递给该方法来渲染给定的类组件:

php
use App\View\Components\HelloComponent;

return Blade::renderComponent(new HelloComponent('Julian Bashir'));

插槽名称快捷方式

插槽名称快捷方式由 Caleb Porzio 贡献。

在 Laravel 的早期版本中,插槽名称是通过在 x-slot 标签上使用 name 属性提供的:

blade
<x-alert>
    <x-slot name="title">
        服务器错误
    </x-slot>

    <strong>哎呀!</strong> 出现了问题!
</x-alert>

然而,从 Laravel 9.x 开始,您可以使用方便的更短语法指定插槽的名称:

xml
<x-slot:title>
    服务器错误
</x-slot>

Checked / Selected Blade 指令

Checked 和 selected Blade 指令由 Ash AllenTaylor Otwell 贡献。

为了方便,您现在可以使用 @checked 指令轻松指示给定的 HTML 复选框输入是否“选中”。如果提供的条件评估为 true,则该指令将输出 checked

blade
<input type="checkbox"
        name="active"
        value="active"
        @checked(old('active', $user->active)) />

同样,@selected 指令可用于指示给定选择选项是否应“被选中”:

blade
<select name="version">
    @foreach ($product->versions as $version)
        <option value="{{ $version }}" @selected(old('version') == $version)>
            {{ $version }}
        </option>
    @endforeach
</select>

Bootstrap 5 分页视图

Bootstrap 5 分页视图由 Jared Lewis 贡献。

Laravel 现在包括使用 Bootstrap 5 构建的分页视图。要使用这些视图而不是默认的 Tailwind 视图,您可以在 App\Providers\AppServiceProvider 类的 boot 方法中调用分页器的 useBootstrapFive 方法:

php
use Illuminate\Pagination\Paginator;

/**
 * 启动任何应用程序服务。
 *
 * @return void
 */
public function boot()
{
    Paginator::useBootstrapFive();
}

改进的嵌套数组数据验证

改进的嵌套数组输入验证由 Steve Bauman 贡献。

有时,您可能需要在为属性分配验证规则时访问给定嵌套数组元素的值。您现在可以使用 Rule::forEach 方法来实现。forEach 方法接受一个闭包,该闭包将在验证的数组属性的每次迭代中被调用,并将接收属性的值和显式的、完全展开的属性名称。闭包应返回要分配给数组元素的规则数组:

php
use App\Rules\HasPermission;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

$validator = Validator::make($request->all(), [
    'companies.*.id' => Rule::forEach(function ($value, $attribute) {
        return [
            Rule::exists(Company::class, 'id'),
            new HasPermission('manage-company', $value),
        ];
    }),
]);

Laravel Breeze API & Next.js

Laravel Breeze API 脚手架和 Next.js 启动包由 Taylor OtwellMiguel Piedrafita 贡献。

Laravel Breeze 启动包已获得“API”脚手架模式和补充的 Next.js 前端实现。此启动包脚手架可用于快速启动作为后端的 Laravel 应用程序,Laravel Sanctum 认证的 API 供 JavaScript 前端使用。

改进的 Ignition 异常页面

Ignition 由 Spatie 开发。

Ignition,Spatie 创建的开源异常调试页面,经过全面重新设计。新的改进版 Ignition 随 Laravel 9.x 一起发布,包含明亮/黑暗主题、可自定义的“在编辑器中打开”功能等。

改进的 route:list CLI 输出

改进的 route:list CLI 输出由 Nuno Maduro 贡献。

route:list CLI 输出在 Laravel 9.x 版本中得到了显著改善,提供了在浏览路由定义时的新体验。

使用 Artisan test 命令的测试覆盖率

使用 Artisan test 命令的测试覆盖率由 Nuno Maduro 贡献。

Artisan test 命令新增了 --coverage 选项,您可以使用该选项来探索您的测试为应用程序提供的代码覆盖率:

shell
php artisan test --coverage

测试覆盖率结果将直接显示在 CLI 输出中。

此外,如果您希望指定测试覆盖率百分比必须达到的最低阈值,可以使用 --min 选项。如果未达到给定的最低阈值,测试套件将失败:

shell
php artisan test --coverage --min=80.3

Soketi Echo 服务器

Soketi Echo 服务器由 Alex Renoki 开发。

虽然并非专属于 Laravel 9.x,Laravel 最近协助编写了 Soketi 的文档,Soketi 是一个与 Laravel Echo 兼容的 Web Socket 服务器,使用 Node.js 编写。Soketi 为那些希望管理自己的 Web Socket 服务器的应用程序提供了一个很好的开源替代方案。

有关使用 Soketi 的更多信息,请查阅 广播文档Soketi 文档

改进的集合 IDE 支持

改进的集合 IDE 支持由 Nuno Maduro 贡献。

Laravel 9.x 为集合组件添加了改进的“通用”样式类型定义,改善了 IDE 和静态分析支持。像 PHPStorm 或静态分析工具如 PHPStan 现在将更好地理解 Laravel 集合。

新助手

Laravel 9.x 引入了两个新的方便助手函数,您可以在自己的应用程序中使用。

str

str 函数返回给定字符串的新 Illuminate\Support\Stringable 实例。此函数等同于 Str::of 方法:

php
$string = str('Taylor')->append(' Otwell');

// 'Taylor Otwell'

如果未提供参数,str 函数将返回 Illuminate\Support\Str 的实例:

php
$snake = str()->snake('LaravelFramework');

// 'laravel_framework'

to_route

to_route 函数为给定的命名路由生成重定向 HTTP 响应,提供了一种从路由和控制器重定向到命名路由的表达方式:

php
return to_route('users.show', ['user' => 1]);

如有必要,您可以将应分配给重定向的 HTTP 状态代码和任何附加响应头作为第三和第四个参数传递给 to_route 方法:

php
return to_route('users.show', ['user' => 1], 302, ['X-Framework' => 'Laravel']);