Laravel 8 中文文档 发行说明
版本化方案
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 设计的,你可以选择 Livewire 或 Inertia 脚手架。
模型类目录
由于压倒性的社区需求,现在默认的 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 Otwell 和 Mohamed Said 共同贡献。
Laravel 的任务批处理特性让你可以简单地执行批量任务,然后在批量任务执行完成后再执行一些操作。
Bus
facade 中新增了一个 batch
方法可以用来执行批量任务。当然,批处理主要是和回调结合使用的。所以,你可能需要使用 then
,catch
,finally
方法来定义完整的回调。这三种回调任意一个被调用时都会接收到一个 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。
测试时, 你有时可能需要修改诸如 now
或 Illuminate\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
中。