# 发行说明

  • 版本计划
  • 支援政策
  • Laravel 8

# 版本计划

Laravel及其其他第一方软件包遵循Semantic Versioning (opens new window)。主要框架版本每六个月(3月和9月)发布,次要版本和修补程序版本可能每周发布一次。次要和修补程序版本应该永远包含重大更改。

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

# 支援政策

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

释放 错误修复,直到 安全修复,直到
6(LTS) 2019年9月3日 2021年10月5日 2022年9月3日
7 2020年3月3日 2020年10月6日 2021年3月3日
8 2020年9月8日 2021年4月6日 2021年9月8日

# Laravel 8

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

# Laravel Jetstream

Laravel Jetstream由Taylor Otwell撰写 (opens new window)

Laravel Jetstream (opens new window)是为Laravel设计的精美应用程序支架。Jetstream为您的下一个项目提供了理想的起点,包括登录,注册,电子邮件验证,身份验证,会话管理,通过Laravel Sanctum提供的API支持以及可选的团队管理。Laravel Jetstream取代并改进了可用于早期版本的Laravel的旧式身份验证UI支架。

Jetstream是使用Tailwind CSS (opens new window)设计的,可以选择Livewire (opens new window)Inertia (opens new window)脚手架。

# 模型目录

通过压倒社区的需求,默认的Laravel应用程序框架现在包含一个app/Models目录。我们希望您喜欢Eloquent的家!所有相关的生成器命令均已更新,以假定app/Models目录中存在模型(如果存在)。如果该目录不存在,框架将假定您的模型应放在该app目录中。

# 模型工厂类

样板工厂班级由Taylor Otwell (opens new window) 贡献。

模型工厂已完全改写为基于类的工厂,并经过改进以提供一流的关系支持。例如,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生成的模型具有新特性,因此可以像以下方式使用模型工厂:

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 (opens new window)软件包,以支持Laravel 8.x中模型工厂的先前迭代。

Laravel重新编写的工厂包含许多我们认为您会喜欢的功能。

# 迁移压缩

由**泰勒·奥特威尔 (opens new window)Taylor Otwell (opens new window)**)贡献。

在构建应用程序时,随着时间的推移,您可能会积累越来越多的迁移。这可能会导致您的迁移目录因潜在的数百次迁移而变得肿。如果您使用的是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将首先执行模式文件的SQL。执行压缩文件的命令后,Laravel将执行任何不属于模式转储的剩余迁移。

# 任务批处理

Taylor Otwell (opens new window)Mohamed Said (opens new window)贡献。

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

Busbatch方法可用于调度一批作业。当然,可以和回调结合使用。所以,你可以使用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 (opens new window)贡献的。

Laravel的请求速率限制器功能已增强,具有更大的灵活性和功能,同时仍保持与先前版本的throttle中间件API的向后兼容性。

速率限制器是使用RateLimiterfacade的for方法定义的。该for方法接受一个速率限制器名称和一个Closure,该Closure返回应用于分配了该速率限制器的路由的限制配置:

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 (opens new window)spatie (opens new window)启发的。

在Laravel的早期版本中,php artisan down可以使用允许访问应用程序的IP地址的“允许列表”来绕过维护模式功能,新版本已删除此功能。使用了更简单的秘密 /令牌机制。

在维护模式下,您可以使用该secret选项指定维护模式令牌:

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

将应用程序置于维护模式后,您可以导航到与该令牌匹配的应用程序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

是由Mohamed Said (opens new window)贡献的。

使用新catch方法,您现在可以提供一个Closure,如果在排队的Closure用尽了队列中所有已配置的重试尝试后未能成功完成,则应该执行该Closure:

use Throwable;

dispatch(function () use ($podcast) {
    $podcast->publish();
})->catch(function (Throwable $e) {
    // This job has failed...
});

# 动态Blade组件

动态Blade组件由Taylor Otwell (opens new window)贡献。

有时您可能需要渲染一个组件,但是直到运行时才知道应该渲染哪个组件。在这种情况下,您现在可以使用Laravel的内置dynamic-component组件根据运行时值或变量来呈现该组件:

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

要了解有关Blade组件的更多信息,请查阅Blade文档。

# 事件监听器的改进

事件监听器的改进由Taylor Otwell (opens new window)贡献。

现在,可以仅通过将Closure传递给Event::listen方法来注册基于Closure的事件侦听器。Laravel将检查闭包,以确定侦听器处理的事件类型:

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

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

另外,现在可以使用以下Illuminate\Events\queueable函数将基于Closure的事件侦听器标记为可排队:

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)));

如果您想处理匿名排队侦听器失败,则可以catch在定义queueable侦听器时为该方法提供闭包:

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 (opens new window)贡献,灵感来自Ruby on Rails。

测试时,您有时可能需要修改诸如now或的帮助程序返回的时间Illuminate\Support\Carbon::now()。Laravel的基本功能测试类现在包括帮助程序,您可以使用它们来操纵当前时间:

public function testTimeCanBeManipulated()
{
    // Travel into the future...
    $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();

    // Travel into the past...
    $this->travel(-5)->hours();

    // Travel to an explicit time...
    $this->travelTo(now()->subHours(6));

    // Return back to the present time...
    $this->travelBack();
}

# Artisan serve改进

Artisan的serve改进由泰勒·奥特威尔 (opens new window)Taylor Otwell) (opens new window)贡献。

serve当在本地.env文件中检测到环境变量更改时,Artisan命令已通过自动重新加载得到了改进。以前,该命令必须手动停止并重新启动。

# Tailwind分页视图

Laravel分页器已更新为默认使用Tailwind CSS (opens new window)框架。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中。