发行说明

未匹配的标注

发行说明

版本化方案

Laravel 及官方发布的包皆遵循 语义化版本。 主要框架版本每六个月发布一次 (2 月和 8 月),而次要和补丁版本可能每周发布一次。次要版本和补丁 绝不 包含非兼容性更改。

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

支持策略

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

版本 发布时间 Bug 修复截止时间 安全修复截止时间
6 (LTS) 2019 年 9 月 3 日 2021 年 9 月 3 日 2022 年 9 月 3 日
7 2020 年 3 月 3 日 2020 年 9 月 3 日 2021 年 3 月 3 日
8 2020 年 9 月 8 日 2021 年 3 月 8 日 2021 年 9 月 8 日

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 目录。我们希望你喜欢 Eloquent 的新家!所有相关的生成器命令均已更新,假定模型存在于 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
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = User::class;

    /**
     * Define the model's default state.
     *
     * @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 trait,因此可以像以下方式使用模型工厂:

use App\Models\User;

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

因为模型工厂现在是简单的 PHP 类,状态转换可以直接写成一个方法。除此之外,你也可以给你的Elequent 模型工厂添加任意你需要的工具类。

例如,你的 User 模型 有个 suspended 属性,现在你想修改它的一个默认的属性值,你可以使用基类工厂类的 state 方法来完成。方法名字可以随意设置,毕竟这是个很典型的 PHP 方法。

/**
 * 表示这个用户处于禁止状态
 *
 * @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 关联方法,我们只需要执行下面的代码就可以生成一个有 3 篇文章的用户。

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

为了简化升级过程,我们发布了一个 laravel/legacy-factories 扩展包,可以在 Laravel 8 中支持以前的模型工厂。

新版的模型工厂还包含了很多特性,我们相信你会喜欢的。想了解更多的话,请查看 数据库测试文档

迁移压缩

迁移压缩由 Taylor Otwell 贡献。

在你开发应用的过程中,随着时间的推移,你的迁移文件可能会累积的越来越多,这可能导致你的迁移目录变得非常臃肿。现在你可以把你的迁移文件压缩成一个 SQL 文件。执行 schema:dump 即可:

php artisan schema:dump

// 转储当前数据库模式并删除所有现有的迁移…
php artisan schema:dump --prune

执行完这条命令,Laravel 将会在 database/schema 目录写入一个「schema」文件。当在未执行任何其他迁移的情况下,你迁移数据库时,Laravel 将会先执行 schema 文件中的 SQL,再执行不包含在 schema 中的剩余迁移。

任务批处理

任务批处理由 Taylor OtwellMohamed Said 共同贡献。

Laravel 的任务批处理特性让你可以简单地执行批量任务,然后在批量任务执行完成后再执行一些操作。

Bus facade 中新增了一个 batch 方法可以用来执行批量任务。当然,批处理主要是和回调结合使用的。所以,你可能需要使用 thencatchfinally 方法来定义完整的回调。这三种回调任意一个被调用时都会接收到一个 Illuminate\Bus\Batch 实例:

use App\Jobs\ProcessPodcast;
use App\Podcast;
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Batch;
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 中间件 将刚刚创建的速率限制器绑定到路由或者路由组就可以了。将速率限制器的名称传入中间件来进行绑定:

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) {
    //
}));

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

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) {
    // The queued listener failed...
}));

时间测试助手

时间测试助手由 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 中。

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

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
上一篇 下一篇
Summer
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
贡献者:12
讨论数量: 0
发起讨论 只看当前版本


暂无话题~