发布说明
版本方案
Laravel 的版本方案遵循以下惯例:paradigm.major.minor
。主要框架版本每六个月发布一次(2 月和 8 月),而次要版本可能每周发布一次。次要版本绝不应包含破坏性更改。
当从您的应用程序或包中引用 Laravel 框架或其组件时,您应始终使用诸如 5.5.*
之类的版本约束,因为 Laravel 的主要版本确实包含破坏性更改。然而,我们努力确保您可以在一天或更短的时间内更新到新的主要版本。
范式转换版本相隔多年,代表框架架构和惯例的根本性转变。目前,没有正在开发的范式转换版本。
为什么 Laravel 不使用语义版本控制?
一方面,Laravel 的所有可选组件(如 Cashier、Dusk、Valet、Socialite 等)确实使用语义版本控制。然而,Laravel 框架本身并没有。原因是语义版本控制是一种“还原主义”的方法,用于确定两个代码片段是否兼容。即使使用语义版本控制,您仍然必须安装升级后的包并运行自动化测试套件,以了解是否有任何与您的代码库实际不兼容的地方。
因此,Laravel 框架使用了一种更能传达发布范围的版本方案。此外,由于次要版本绝不包含故意的破坏性更改,只要您的版本约束遵循 paradigm.major.*
约定,您就不应收到破坏性更改。
支持政策
对于 LTS 版本,例如 Laravel 5.5,提供 2 年的错误修复和 3 年的安全修复。这些版本提供最长的支持和维护窗口。对于一般版本,提供 6 个月的错误修复和 1 年的安全修复。
Laravel 5.5 (LTS)
Laravel 5.5 通过添加包自动检测、API 资源/转换、控制台命令自动注册、队列作业链、队列作业速率限制、基于时间的作业尝试、可渲染的邮件、可渲染和可报告的异常、更一致的异常处理、数据库测试改进、更简单的自定义验证规则、React 前端预设、Route::view
和 Route::redirect
方法、Memcached 和 Redis 缓存驱动的“锁”、按需通知、Dusk 中的无头 Chrome 支持、便捷的 Blade 快捷方式、改进的受信代理支持等功能,继续了 Laravel 5.4 的改进。
此外,Laravel 5.5 与 Laravel Horizon 的发布同时进行,这是一个美丽的新队列仪表板和配置系统,适用于基于 Redis 的 Laravel 队列。
本文档总结了框架的最显著改进;然而,更详细的变更日志始终可在 GitHub 上找到。
Laravel Horizon
Horizon 为您的 Laravel 驱动的 Redis 队列提供了一个美丽的仪表板和代码驱动的配置。Horizon 允许您轻松监控队列系统的关键指标,如作业吞吐量、运行时间和作业失败。
所有的工作者配置都存储在一个简单的配置文件中,允许您的配置保留在源代码控制中,您的整个团队可以协作。
有关 Horizon 的更多信息,请查看 完整的 Horizon 文档。
包发现
Laracasts 上有一个免费的 视频教程 可用于此功能。
在 Laravel 的早期版本中,安装包通常需要几个额外的步骤,例如将服务提供者添加到您的 app
配置文件中并注册任何相关的 facade。然而,从 Laravel 5.5 开始,Laravel 可以自动检测和注册服务提供者和 facade。
例如,您可以通过在您的 Laravel 应用程序中安装流行的 barryvdh/laravel-debugbar
包来体验这一点。通过 Composer 安装包后,调试栏将可用于您的应用程序,无需额外配置:
composer require barryvdh/laravel-debugbar
包开发人员只需将他们的服务提供者和 facade 添加到包的 composer.json
文件中:
"extra": {
"laravel": {
"providers": [
"Laravel\\Tinker\\TinkerServiceProvider"
]
}
},
有关更新您的包以使用服务提供者和 facade 发现的更多信息,请查看 包开发 的完整文档。
API 资源
构建 API 时,您可能需要一个转换层,位于 Eloquent 模型和实际返回给应用程序用户的 JSON 响应之间。Laravel 的资源类允许您以富有表现力和简单的方式将模型和模型集合转换为 JSON。
资源类表示需要转换为 JSON 结构的单个模型。例如,这里是一个简单的 UserResource
类:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
class UserResource extends Resource
{
/**
* 将资源转换为数组。
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
当然,这只是 API 资源的最基本示例。Laravel 还提供了多种方法来帮助您构建资源和资源集合。有关更多信息,请查看 API 资源 的完整文档。
控制台命令自动注册
Laracasts 上有一个免费的 视频教程 可用于此功能。
创建新控制台命令时,您不再需要手动将它们列在 Console 内核的 $commands
属性中。相反,从内核的 commands
方法中调用一个新的 load
方法,该方法将扫描给定目录中的任何控制台命令并自动注册它们:
/**
* 为应用程序注册命令。
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
// ...
}
新的前端预设
Laracasts 上有一个免费的 视频教程 可用于此功能。
虽然基本的 Vue 脚手架仍包含在 Laravel 5.5 中,但现在有几种新的前端预设选项。在一个新的 Laravel 应用程序中,您可以使用 preset
命令将 Vue 脚手架替换为 React 脚手架:
php artisan preset react
或者,您可以使用 none
预设完全删除 JavaScript 和 CSS 框架脚手架。此预设将使您的应用程序仅保留一个简单的 Sass 文件和一些简单的 JavaScript 实用程序:
php artisan preset none
这些命令仅用于在新的 Laravel 安装上运行。它们不应在现有应用程序上使用。
队列作业链
作业链允许您指定一系列应按顺序运行的队列作业。如果序列中的一个作业失败,其余作业将不会运行。要执行队列作业链,您可以在任何可调度的作业上使用 withChain
方法:
ProvisionServer::withChain([
new InstallNginx,
new InstallPhp
])->dispatch();
队列作业速率限制
如果您的应用程序与 Redis 交互,您现在可以按时间或并发限制队列作业的速率。当您的队列作业与速率限制的 API 交互时,此功能可能会有所帮助。例如,您可以将某种类型的作业限制为每 60 秒仅运行 10 次:
Redis::throttle('key')->allow(10)->every(60)->then(function () {
// 作业逻辑...
}, function () {
// 无法获取锁...
return $this->release(10);
});
在上面的示例中,key
可以是任何唯一标识您希望速率限制的作业类型的字符串。例如,您可能希望根据作业的类名和它操作的 Eloquent 模型的 ID 构建键。
或者,您可以指定同时处理给定作业的最大工作者数量。当队列作业正在修改一个应该仅由一个作业一次修改的资源时,这可能会有所帮助。例如,我们可以将某种类型的作业限制为仅由一个工作者同时处理:
Redis::funnel('key')->limit(1)->then(function () {
// 作业逻辑...
}, function () {
// 无法获取锁...
return $this->release(10);
});
基于时间的作业尝试
作为定义作业在失败前可以尝试的次数的替代方法,您现在可以定义作业应超时的时间。这允许在给定时间范围内尝试任何次数的作业。要定义作业应超时的时间,请在作业类中添加 retryUntil
方法:
/**
* 确定作业应超时的时间。
*
* @return \DateTime
*/
public function retryUntil()
{
return now()->addSeconds(5);
}
您还可以在队列事件监听器上定义 retryUntil
方法。
验证规则对象
Laracasts 上有一个免费的 视频教程 可用于此功能。
验证规则对象为您的应用程序提供了一种新的、紧凑的方式来添加自定义验证规则。在 Laravel 的早期版本中,Validator::extend
方法用于通过闭包添加自定义验证规则。然而,这可能会变得繁琐。在 Laravel 5.5 中,一个新的 make:rule
Artisan 命令将在 app/Rules
目录中生成一个新的验证规则:
php artisan make:rule ValidName
规则对象只有两个方法:passes
和 message
。passes
方法接收属性值和名称,并应根据属性值是否有效返回 true
或 false
。message
方法应返回验证失败时应使用的验证错误消息:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class ValidName implements Rule
{
/**
* 确定验证规则是否通过。
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return strlen($value) === 6;
}
/**
* 获取验证错误消息。
*
* @return string
*/
public function message()
{
return '名称必须为六个字符长。';
}
}
定义规则后,您可以通过将规则对象的实例与其他验证规则一起传递来使用它:
use App\Rules\ValidName;
$request->validate([
'name' => ['required', new ValidName],
]);
受信代理集成
在负载均衡器后运行应用程序时,负载均衡器终止 TLS / SSL 证书,您可能会注意到您的应用程序有时不会生成 HTTPS 链接。通常这是因为您的应用程序正在从负载均衡器转发端口 80 上的流量,并不知道它应该生成安全链接。
为了解决这个问题,许多 Laravel 用户安装了 Chris Fidao 的 Trusted Proxies 包。由于这是一个常见的用例,Chris 的包现在默认随 Laravel 5.5 一起提供。
默认的 Laravel 5.5 应用程序中包含一个新的 App\Http\Middleware\TrustProxies
中间件。此中间件允许您快速自定义应用程序应信任的代理:
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
/**
* 此应用程序的受信代理。
*
* @var array
*/
protected $proxies;
/**
* 当前代理头映射。
*
* @var array
*/
protected $headers = [
Request::HEADER_FORWARDED => 'FORWARDED',
Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
];
}
按需通知
有时您可能需要向不是您应用程序“用户”的人发送通知。使用新的 Notification::route
方法,您可以在发送通知之前指定临时通知路由信息:
Notification::route('mail', 'taylor@laravel.com')
->route('nexmo', '5555555555')
->send(new InvoicePaid($invoice));
可渲染的邮件
Laracasts 上有一个免费的 视频教程 可用于此功能。
邮件现在可以直接从路由返回,允许您快速在浏览器中预览邮件的设计:
Route::get('/mailable', function () {
$invoice = App\Invoice::find(1);
return new App\Mail\InvoicePaid($invoice);
});
可渲染和可报告的异常
Laracasts 上有一个免费的 视频教程 可用于此功能。
在 Laravel 的早期版本中,您可能不得不在异常处理程序中使用“类型检查”来为给定异常渲染自定义响应。例如,您可能在异常处理程序的 render
方法中编写了这样的代码:
/**
* 将异常渲染为 HTTP 响应。
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
if ($exception instanceof SpecialException) {
return response(...);
}
return parent::render($request, $exception);
}
在 Laravel 5.5 中,您现在可以直接在异常上定义一个 render
方法。这允许您将自定义响应渲染逻辑直接放在异常上,这有助于避免在异常处理程序中累积条件逻辑。如果您还想自定义异常的报告逻辑,可以在类上定义一个 report
方法:
<?php
namespace App\Exceptions;
use Exception;
class SpecialException extends Exception
{
/**
* 报告异常。
*
* @return void
*/
public function report()
{
//
}
/**
* 渲染异常。
*
* @param \Illuminate\Http\Request
* @return void
*/
public function render($request)
{
return response(...);
}
}
请求验证
Laracasts 上有一个免费的 视频教程 可用于此功能。
Illuminate\Http\Request
对象现在提供了一个 validate
方法,允许您从路由闭包或控制器中快速验证传入请求:
use Illuminate\Http\Request;
Route::get('/comment', function (Request $request) {
$request->validate([
'title' => 'required|string',
'body' => 'required|string',
]);
// ...
});
一致的异常处理
验证异常处理现在在整个框架中是一致的。以前,框架中有多个位置需要自定义以更改 JSON 验证错误响应的默认格式。此外,Laravel 5.5 中 JSON 验证响应的默认格式现在遵循以下约定:
{
"message": "给定的数据无效。",
"errors": {
"field-1": [
"错误 1",
"错误 2"
],
"field-2": [
"错误 1",
"错误 2"
],
}
}
所有 JSON 验证错误格式化都可以通过在 App\Exceptions\Handler
类上定义一个方法来控制。例如,以下自定义将使用 Laravel 5.4 约定格式化 JSON 验证响应。
use Illuminate\Validation\ValidationException;
/**
* 将验证异常转换为 JSON 响应。
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Validation\ValidationException $exception
* @return \Illuminate\Http\JsonResponse
*/
protected function invalidJson($request, ValidationException $exception)
{
return response()->json($exception->errors(), $exception->status);
}
缓存锁
Redis 和 Memcached 缓存驱动程序现在支持获取和释放原子“锁”。这提供了一种简单的方法来获取任意锁,而无需担心竞争条件。例如,在执行任务之前,您可能希望获取一个锁,以便没有其他进程尝试已经在进行的相同任务:
if (Cache::lock('lock-name', 60)->get()) {
// 锁定 60 秒,继续处理...
Cache::lock('lock-name')->release();
} else {
// 无法获取锁...
}
或者,您可以将闭包传递给 get
方法。只有在可以获取锁时才会执行闭包,并且在闭包执行后锁将自动释放:
Cache::lock('lock-name', 60)->get(function () {
// 锁定 60 秒...
});
此外,您可以“阻塞”直到锁可用:
if (Cache::lock('lock-name', 60)->block(10)) {
// 最多等待 10 秒以获取锁...
}
Blade 改进
Laracasts 上有一个免费的 视频教程 可用于此功能。
编写自定义指令有时比定义简单的自定义条件语句更复杂。为此,Blade 现在提供了一个 Blade::if
方法,允许您使用闭包快速定义自定义条件指令。例如,让我们在 AppServiceProvider
的 boot
方法中定义一个检查当前应用程序环境的自定义条件:
use Illuminate\Support\Facades\Blade;
/**
* 执行服务的注册后引导。
*
* @return void
*/
public function boot()
{
Blade::if('env', function ($environment) {
return app()->environment($environment);
});
}
定义自定义条件后,我们可以轻松地在模板中使用它:
@env('local')
// 应用程序在本地环境中...
@else
// 应用程序不在本地环境中...
@endenv
除了能够轻松定义自定义 Blade 条件指令外,还添加了新的快捷方式,以便快速检查当前用户的身份验证状态:
@auth
// 用户已通过身份验证...
@endauth
@guest
// 用户未通过身份验证...
@endguest
新的路由方法
Laracasts 上有一个免费的 视频教程 可用于此功能。
如果您正在定义一个重定向到另一个 URI 的路由,您现在可以使用 Route::redirect
方法。此方法提供了一个便捷的快捷方式,因此您不必为执行简单的重定向定义完整的路由或控制器:
Route::redirect('/here', '/there', 301);
如果您的路由只需要返回一个视图,您现在可以使用 Route::view
方法。与 redirect
方法一样,此方法提供了一个简单的快捷方式,因此您不必定义完整的路由或控制器。view
方法接受 URI 作为第一个参数,视图名称作为第二个参数。此外,您可以提供一个数据数组作为可选的第三个参数传递给视图:
Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
“粘性”数据库连接
sticky
选项
配置读/写数据库连接时,可以使用一个新的 sticky
配置选项:
'mysql' => [
'read' => [
'host' => '192.168.1.1',
],
'write' => [
'host' => '196.168.1.2'
],
'sticky' => true,
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
],
sticky
选项是一个可选值,可用于允许在当前请求周期内立即读取已写入数据库的记录。如果启用了 sticky
选项,并且在当前请求周期内对数据库执行了“写入”操作,则任何进一步的“读取”操作将使用“写入”连接。这确保了在请求周期内写入的数据可以在同一请求期间立即从数据库中读取。由您决定这是否是您应用程序所需的行为。