发行说明

未匹配的标注

发行说明

版本化方案

Laravel 及官方发布的包皆遵循 语义化版本。 主要的框架版本每年「9月」发布,而次要的和补丁版本可能每周发布一次。次要版本和修补程序版本应 从不 包含非兼容性的更改。

你从应用或包中引用 Laravel 框架或其组件时,应始终使用版本约束,如 ^8.0 ,因为 Laravel 的主要版本确实包含非兼容性更改。但是,我们努力确保您可以在一天或更短的时间内更新到新的主要版本。

异常

命名参数

目前,PHP的 命名参数 功能还没有被 Laravel 的向后兼容性指南所涵盖。我们可以在必要时选择重命名函数参数,以改进Laravel 代码库。因此,在调用 Laravel 方法时使用命名参数应该谨慎,并且要理解参数名将来可能会改变。

支持策略

对于 LTS 版本,例如 Laravel 6,提供了 2 年的错误修复和 3 年的安全修复。这些版本提供了最长的支持和维护窗口。对于一般的发行版本,只提供了 18 个月的错误修复和 2 年的安全修复。对于包括 Lumen 在内的所有其他版本,只有最新版本才会修复错误。此外,请查阅 Laravel 支持的 数据库版本

版本 发行时间 Bug 修复截止时间 安全修复截止时间
6 (LTS) 2019 年 9 月 3 日 2021 年 9 月 7 日 2022 年 9 月 6 日
7 2020 年 3 月 3 日 2020 年 10 月 6 日 2021 年 3 月 3 日
8 2020 年 9 月 8 日 2022 年 3 月 1 日 2022 年 9 月 6 日
9 (LTS) 2022 年 1 月 25 日 2024 年 1 月 30 日 2025 年 1 月 28 日
10 2023 年 1 月 24 日 2024 年 7 月 30 日 2025 年 1 月 28 日

Laravel 8

Laravel 8 通过引入 Laravel Jetstream,模型工厂类,迁移压缩,任务批处理,改善的速率限制,队列改进,动态 Blade 组件,Tailwind 分页视图,时间测试助手,对 artisan serve 的改进,事件侦听器的改进,以及各种其他错误修复和可用性改进,对 Laravel 7.x 继续进行了改善。

Laravel Jetstream

Laravel Jetstream 由 Taylor Otwell 撰写。

Laravel Jetstream 是为 Laravel 设计的精美的应用程序脚手架。Jetstream 为你的下一个项目提供了完美的起点,包括登录、注册、电子邮件验证、双因子认证、会话管理、通过 Laravel Sanctum 的 API 支持以及可选的团队管理。Laravel Jetstream 替代并改进了可用于早期版本 Laravel 的旧式身份验证 UI 框架。

Jetstream是使用 Tailwind CSS 设计的,你可以使用 LivewireInertia 脚手架。

模型类目录

由于大量的社区需求,现在默认的 Laravel 框架包含了一个 app/Models 目录。我们希望您喜欢这个设置!所有相关的生成器命令均已更新,假定模型存在于 app/models 目录中(如果存在)。如果目录不存在,则框架将假定你的模型应该放在 app 目录中。

模型工厂类

模型工厂类由 Taylor Otwell 撰写。
Eloquent 模型工厂 已经完全重写为基于类的工厂,并有完美的关联支持。例如,包含在 Laravel 中的 UserFactory 是这样写的:

<?php

namespace Database\Factories;

use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class UserFactory extends Factory
{
    /**
     * 工厂对应的模型名称。
     *
     * @var string
     */
    protected $model = User::class;

    /**
     * 定义模型的默认状态。
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => $this->faker->name,
            'email' => $this->faker->unique()->safeEmail,
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }
}

由于在生成的模型上提供了新的“HasFactory”特性,因此可以这样使用模型工厂:

use App\Models\User;

User::factory()->count(50)->create();

由于模型工厂现在是简单的 PHP 类,状态转换可以写成类方法。此外,您可以根据需要将任何其他助手类添加到您的 Eloquent 模型工厂中。

例如,您的 User 模型可能有一个 suspended 状态,该状态会修改其默认属性值之一。可以使用基本工厂的 state 方法定义状态转换。你可以随意命名你的状态方法。毕竟,这只是一个典型的 PHP 方法:

/**
 * Indicate that the user is suspended.
 *
 * @return \Illuminate\Database\Eloquent\Factories\Factory
 */
public function suspended()
{
    return $this->state([
        'account_status' => 'suspended',
    ]);
}

在定义了状态转换方法之后,我们可以这样使用它:

use App\Models\User;

User::factory()->count(5)->suspended()->create();

如前所述,Laravel 8 的模型工厂包含对关系的一流支持。因此,假设我们的 User 模型具有 posts 关系方法,我们可以简单地运行以下代码来生成具有三个帖子的用户:

$users = User::factory()
            ->hasPosts(3, [
                'published' => false,
            ])
            ->create();

为了简化升级过程,laravel/legacy factories 这个包的发布是为了支持Laravel 8.x 中模型工厂的上一次迭代。
Laravel 的重新编写的工厂包含许多我们认为您会喜欢的功能。要了解更多关于模型工厂的信息,请参考 数据库测试文档

迁移-压缩

迁移压缩由 Taylor Otwell 贡献。

在构建应用程序时,随着时间的推移,您可能会积累越来越多的迁移。这可能会导致您的迁移目录因潜在的数百次迁移而变得臃肿。如果您使用的是 MySQL 或 PostgreSQL,则现在可以将迁移“压缩”到单个SQL文件中。首先,执行 schema:dump 命令:

php artisan schema:dump

// Dump the current database schema and prune all existing migrations...
php artisan schema:dump --prune

当您执行此命令时,Laravel将在您的 database / schema 目录中写入一个 schema 文件。

当您尝试执行数据迁移,并且在此前未执行过任何其他迁移时,Laravel将首先执行schema文件的SQL。随后,Laravel将继续执行其它不在schema文件中的数据迁移。

作业批处理

Job 批处理由 Taylor Otwell & Mohamed Said 贡献。

Laravel 的作业批处理功能使您可以轻松地执行一批作业,然后在一批作业完成执行后执行一些操作。

可以使用 Bus 门面的新 batch 方法来分派一批作业。当然,与完成回调结合使用时,批处理主要有用。因此,您可以使用 thencatchfinally 方法来定义批处理的完成回调。这些回调中的每一个在调用时都会收到一个 Illuminate\Bus\Batch 实例:

use App\Jobs\ProcessPodcast;
use App\Podcast;
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;
use Throwable;

$batch = Bus::batch([
    new ProcessPodcast(Podcast::find(1)),
    new ProcessPodcast(Podcast::find(2)),
    new ProcessPodcast(Podcast::find(3)),
    new ProcessPodcast(Podcast::find(4)),
    new ProcessPodcast(Podcast::find(5)),
])->then(function (Batch $batch) {
    // All jobs completed successfully...
})->catch(function (Batch $batch, Throwable $e) {
    // First batch job failure detected...
})->finally(function (Batch $batch) {
    // The batch has finished executing...
})->dispatch();

return $batch->id;

想了解更多关于任务批处理,请查看 队列文档

速率优化

速率优化由 Taylor Otwell 贡献。

Laravel 的请求速率限制器得到了增强,具有更大的灵活性和功能,同时兼容上一个版本的 throttle 中间件。

使用 RateLimiter facade 的 for 方法来定义一个速率限制器。for 方法第一个参数是速率限制器名称,第二个参数是一个闭包函数,该闭包函数返回速率限制器的配置:

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;

RateLimiter::for('global', function (Request $request) {
    return Limit::perMinute(1000);
});

由于速率限制器的回调函数传入的是一个 HTTP 请求实例,你可以基于请求或当前认证的用户来动态设置速率限制:

RateLimiter::for('uploads', function (Request $request) {
    return $request->user()->vipCustomer()
                ? Limit::none()
                : Limit::perMinute(100);
});

有时你可能希望根据一些特定的值来进行速率限制。比如你希望限制用户每分钟内每个 IP 地址最多发起 100 次请求,你可以使用 by 方法来实现这一功能:

RateLimiter::for('uploads', function (Request $request) {
    return $request->user()->vipCustomer()
                ? Limit::none()
                : Limit::perMinute(100)->by($request->ip());
});

可以使用 throttle 中间件 将速率限制器绑定到路由或路由组。将速率限制器的名称传入 throttle 中间件来进行绑定:

Route::middleware(['throttle:uploads'])->group(function () {
    Route::post('/audio', function () {
        //
    });

    Route::post('/video', function () {
        //
    });
});

想了解更多关于速率限制器,请查看 路由文档

维护模式优化

维护模式优化由 Taylor Otwell 贡献, 灵感来源于 Spatie

在之前的 Laravel 版本中,php artisan down 开启的维护模式可以通过建立一个 IP 地址白名单来绕过,在白名单中的 IP 地址可以正常访问应用。在新版本中这个特性被移除了,取而代之的是一个简单的「密码」或者说 token 方案。

在维护模式下,你可以通过 secret 选项生成一个可以绕过维护模式的 token:

php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"

将应用设置为维护模式后,你可以带上这个 token 访问应用程序的 URL,然后 Laravel 将会在浏览器中写入一个能绕过维护模式的 cookie:

https://example.com/1630542a-246b-4b66-afa1-dd72a4c43515

通过这个隐藏路由,你会被重定向到应用的 / 路由。一旦 cookie 被写入浏览器,你就可以像没开启维护模式一样正常的访问应用。

预渲染维护模式视图

如果你在部署时使用了 php artisan down,你的用户又在你更新 composer 依赖或其他基础视图时访问应用,可能偶尔还是会出错。出现这种情况是因为 Laravel 必须先启动一些核心的功能,来确定你的应用是否处于维护模式,然后用模板引擎渲染维护模式视图。

由于这个原因,Laravel 现在允许你在请求的生命周期的最开始预渲染一个维护模式视图。这个视图会在应用的任何依赖加载之前渲染。你可以使用 down 命令的 render 选项选择一个预渲染模板:

php artisan down --render="errors::503"

闭包分发 / 链式 catch

Catch 优化由 Mohamed Said 贡献。

使用新增的 catch 方法,你现在可以提供一个闭包函数来监听某个闭包队列。当闭包队列耗尽了队列配置的所有重置次数后还没有完全成功,就会执行该闭包函数:

use Throwable;

dispatch(function () use ($podcast) {
    $podcast->publish();
})->catch(function (Throwable $e) {
    // 任务失败...
});

动态 Blade 组件

动态 Blade 组件由 Taylor Otwell 贡献。

有时你需要渲染一个组件,但是不确定在运行时应该渲染哪个组件。在这种情况下,你现在可以使用 Laravel 内置的 dynamic-component 组件去根据运行时的某个值或某个变量来动态渲染组件:

<x-dynamic-component :component="$componentName" class="mt-4" />

想了解更多关于 Blade 组件,请查看 Blade 文档

事件监听器优化

事件监听器优化由 Taylor Otwell 贡献。

现在可以通过给 Event::listen 方法传入一个闭包函数来简单的注册一个基于闭包的事件监听器。Laravel 会检查闭包以确定监听器处理的事件类型。

use App\Events\PodcastProcessed;
use Illuminate\Support\Facades\Event;

Event::listen(function (PodcastProcessed $event) {
    //
});

此外,现在可以使用 Illumate\Events\Queueable 函数将基于闭包的事件监听器标记为可排队:

use App\Events\PodcastProcessed;
use function Illuminate\Events\queueable;
use Illuminate\Support\Facades\Event;

Event::listen(queueable(function (PodcastProcessed $event) {
    //
}));

像队列任务一样,你可以使用 onConnectiononQueuedelay 方法自定义队列监听器的执行:

Event::listen(queueable(function (PodcastProcessed $event) {
    //
})->onConnection('redis')->onQueue('podcasts')->delay(now()->addSeconds(10)));

如果你想处理匿名队列的监听器故障,可以在定义 queueable 监听器时给 catch 方法提供一个闭包:

use App\Events\PodcastProcessed;
use function Illuminate\Events\queueable;
use Illuminate\Support\Facades\Event;
use Throwable;

Event::listen(queueable(function (PodcastProcessed $event) {
    //
})->catch(function (PodcastProcessed $event, Throwable $e) {
    // 队列监听器失败...
}));

时间测试助手

时间测试助手由 Taylor Otwell 贡献,灵感来源于 Ruby on Rails。

测试时, 你有时可能需要修改诸如 nowIlluminate\Support\Carbon::now() 之类的函数返回的时间。Laravel 的基本功能测试类现在包括时间测试助手函数,你可以使用它们来操纵当前时间:

public function testTimeCanBeManipulated()
{
    // 设置未来的时间...
    $this->travel(5)->milliseconds();
    $this->travel(5)->seconds();
    $this->travel(5)->minutes();
    $this->travel(5)->hours();
    $this->travel(5)->days();
    $this->travel(5)->weeks();
    $this->travel(5)->years();

    // 设置过去的时间...
    $this->travel(-5)->hours();

    // 设置指定时间...
    $this->travelTo(now()->subHours(6));

    // 设置为当前时间...
    $this->travelBack();
}

Artisan serve 改进

Artisan serve 改进由 Taylor Otwell 贡献。

当本地 .env 文件中的环境变量被修改时 Artisan serve 命令会自动重新加载。在此之前,该命令必须手动停止和重启。

Tailwind 分页视图

Laravel 分页器已更新为默认使用 Tailwind CSS 框架。 Tailwind CSS 是一个高度可定制的低等级 CSS 框架,它为你提供了构建定制设计所需的所有构造块,而无需你烦恼地重写任何烦人的自以为是的样式。当然,Bootstrap 3 和 4 视图仍然可用。

路由命名空间更新

在Laravel的早期版本中,RouteServiceProvider 具有 $namespace 属性。该属性的值将自动添加到控制器路由定义的前缀,并调用 action 助手函数或者 URL::action 方法。在 Laravel 8.x 中,默认情况下此属性为 null。这意味着 Laravel 不会自动命名空间前缀。因此,在新的 Laravel 8.x 应用程序中,应使用标准的 PHP 语法定义控制器路由:

use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']);

对与 action 相关的方法的调用应使用相同的调用语法:

action([UserController::class, 'index']);

return Redirect::action([UserController::class, 'index']);

如果你更喜欢 Laravel 7.x 那种控制器的路由前缀,则可以简单地将 $namespace 属性添加到应用程序的 RouteServiceProvider 中。

注意:此更改仅影响新的 Laravel 8.x 应用程序。从 Laravel 7.x 升级的应用在 RouteServiceProvider 仍然保留 $namespace 属性。

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
上一篇 下一篇
Summer
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
贡献者:12
讨论数量: 0
发起讨论 只看当前版本


暂无话题~