发布说明
版本控制方案
Laravel 及其其他第一方包遵循语义化版本控制。主要框架版本每六个月发布一次(2月和8月),而次要和补丁版本可能每周发布一次。次要和补丁版本绝不应包含破坏性更改。
当从您的应用程序或包中引用 Laravel 框架或其组件时,您应始终使用诸如 ^6.0
之类的版本约束,因为 Laravel 的主要版本确实包含破坏性更改。然而,我们始终努力确保您可以在一天或更短的时间内更新到新的主要版本。
支持政策
对于 LTS 版本,例如 Laravel 6,提供 2 年的错误修复和 3 年的安全修复。这些版本提供最长的支持和维护窗口。对于一般版本,提供 6 个月的错误修复和 1 年的安全修复。对于所有其他库,包括 Lumen,只有最新版本会收到错误修复。此外,请查看 Laravel 支持的数据库版本。
版本 | 发布 | 错误修复截止日期 | 安全修复截止日期 |
---|---|---|---|
5.5 (LTS) | 2017年8月30日 | 2019年8月30日 | 2020年8月30日 |
5.6 | 2018年2月7日 | 2018年8月7日 | 2019年2月7日 |
5.7 | 2018年9月4日 | 2019年3月4日 | 2019年9月4日 |
5.8 | 2019年2月26日 | 2019年8月26日 | 2020年2月26日 |
6 (LTS) | 2019年9月3日 | 2021年9月3日 | 2022年9月3日 |
Laravel 6
Laravel 6 (LTS) 通过引入语义化版本控制、与 Laravel Vapor 的兼容性、改进的授权响应、作业中间件、惰性集合、子查询改进、将前端脚手架提取到 laravel/ui
Composer 包中,以及各种其他错误修复和可用性改进,继续了 Laravel 5.8 的改进。
语义化版本控制
Laravel 框架 (laravel/framework
) 包现在遵循语义化版本控制标准。这使得框架与其他已经遵循此版本控制标准的第一方 Laravel 包保持一致。Laravel 的发布周期将保持不变。
Laravel Vapor 兼容性
Laravel Vapor 由 Taylor Otwell 构建。
Laravel 6 提供了与 Laravel Vapor 的兼容性,Vapor 是一个用于 Laravel 的自动扩展无服务器部署平台。Vapor 抽象了在 AWS Lambda 上管理 Laravel 应用程序的复杂性,以及与 SQS 队列、数据库、Redis 集群、网络、CloudFront CDN 等的接口。
通过 Ignition 改进的异常
Laravel 6 附带了 Ignition,这是由 Freek Van der Herten 和 Marcel Pociot 创建的新开源异常详细信息页面。Ignition 提供了许多比以前版本更好的功能,例如改进的 Blade 错误文件和行号处理、常见问题的可运行解决方案、代码编辑、异常共享和改进的用户体验。
改进的授权响应
改进的授权响应由 Gary Green 实现。
在以前的 Laravel 版本中,很难检索和向最终用户公开自定义授权消息。这使得很难向最终用户解释为什么特定请求被拒绝。在 Laravel 6 中,现在可以更轻松地使用授权响应消息和新的 Gate::inspect
方法。例如,给定以下策略方法:
/**
* 确定用户是否可以查看给定的航班。
*
* @param \App\User $user
* @param \App\Flight $flight
* @return mixed
*/
public function view(User $user, Flight $flight)
{
return $this->deny('拒绝的解释。');
}
授权策略的响应和消息可以使用 Gate::inspect
方法轻松检索:
$response = Gate::inspect('view', $flight);
if ($response->allowed()) {
// 用户被授权查看航班...
}
if ($response->denied()) {
echo $response->message();
}
此外,当从您的路由或控制器中使用诸如 $this->authorize
或 Gate::authorize
之类的辅助方法时,这些自定义消息将自动返回到您的前端。
作业中间件
作业中间件由 Taylor Otwell 实现。
作业中间件允许您在队列作业的执行过程中包装自定义逻辑,从而减少作业本身的样板代码。例如,在以前的 Laravel 版本中,您可能会在作业的 handle
方法的逻辑中包装一个限速回调:
/**
* 执行作业。
*
* @return void
*/
public function handle()
{
Redis::throttle('key')->block(0)->allow(1)->every(5)->then(function () {
info('锁已获得...');
// 处理作业...
}, function () {
// 无法获得锁...
return $this->release(5);
});
}
在 Laravel 6 中,这个逻辑可以提取到作业中间件中,从而使您的作业的 handle
方法不再承担任何限速责任:
<?php
namespace App\Jobs\Middleware;
use Illuminate\Support\Facades\Redis;
class RateLimited
{
/**
* 处理队列作业。
*
* @param mixed $job
* @param callable $next
* @return mixed
*/
public function handle($job, $next)
{
Redis::throttle('key')
->block(0)->allow(1)->every(5)
->then(function () use ($job, $next) {
// 锁已获得...
$next($job);
}, function () use ($job) {
// 无法获得锁...
$job->release(5);
});
}
}
创建中间件后,可以通过从作业的 middleware
方法返回它们来将它们附加到作业:
use App\Jobs\Middleware\RateLimited;
/**
* 获取作业应通过的中间件。
*
* @return array
*/
public function middleware()
{
return [new RateLimited];
}
惰性集合
惰性集合由 Joseph Silber 实现。
许多开发人员已经享受到了 Laravel 强大的集合方法。为了补充已经强大的 Collection
类,Laravel 6 引入了一个 LazyCollection
,它利用 PHP 的生成器来允许您处理非常大的数据集,同时保持内存使用量低。
例如,假设您的应用程序需要处理一个多千兆字节的日志文件,同时利用 Laravel 的集合方法来解析日志。与其一次性将整个文件读入内存,不如使用惰性集合来在给定时间内仅将文件的一小部分保留在内存中:
use App\LogEntry;
use Illuminate\Support\LazyCollection;
LazyCollection::make(function () {
$handle = fopen('log.txt', 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
})
->chunk(4)
->map(function ($lines) {
return LogEntry::fromLines($lines);
})
->each(function (LogEntry $logEntry) {
// 处理日志条目...
});
或者,假设您需要遍历 10,000 个 Eloquent 模型。当使用传统的 Laravel 集合时,所有 10,000 个 Eloquent 模型必须同时加载到内存中:
$users = App\User::all()->filter(function ($user) {
return $user->id > 500;
});
然而,从 Laravel 6 开始,查询构建器的 cursor
方法已更新为返回一个 LazyCollection
实例。这允许您仍然只对数据库运行一个查询,但同时也只在内存中保留一个 Eloquent 模型。在此示例中,filter
回调不会在我们实际逐个迭代每个用户之前执行,从而大大减少了内存使用:
$users = App\User::cursor()->filter(function ($user) {
return $user->id > 500;
});
foreach ($users as $user) {
echo $user->id;
}
Eloquent 子查询增强
Eloquent 子查询增强由 Jonathan Reinink 实现。
Laravel 6 引入了几个新的增强和改进的数据库子查询支持。例如,假设我们有一个航班 destinations
表和一个 flights
表。flights
表包含一个 arrived_at
列,指示航班到达目的地的时间。
使用 Laravel 6 中的新子查询选择功能,我们可以使用单个查询选择所有 destinations
和最近到达该目的地的航班的名称:
return Destination::addSelect(['last_flight' => Flight::select('name')
->whereColumn('destination_id', 'destinations.id')
->orderBy('arrived_at', 'desc')
->limit(1)
])->get();
此外,我们可以使用添加到查询构建器的 orderBy
函数的新子查询功能,根据最后一次航班到达目的地的时间对所有目的地进行排序。同样,这可以在对数据库执行单个查询的同时完成:
return Destination::orderByDesc(
Flight::select('arrived_at')
->whereColumn('destination_id', 'destinations.id')
->orderBy('arrived_at', 'desc')
->limit(1)
)->get();
Laravel UI
以前版本的 Laravel 通常提供的前端脚手架已被提取到 laravel/ui
Composer 包中。这允许第一方 UI 脚手架与主框架分开开发和版本化。由于此更改,默认框架脚手架中不再存在 Bootstrap 或 Vue 代码,并且 make:auth
命令也已从框架中提取。
为了恢复以前版本的 Laravel 中存在的传统 Vue / Bootstrap 脚手架,您可以安装 laravel/ui
包并使用 ui
Artisan 命令安装前端脚手架:
composer require laravel/ui "^1.0" --dev
php artisan ui vue --auth