17611538698
webmaster@21cto.com

Laravel 5.5 新特性预览

资讯 0 2146 2017-09-14 12:02:04
laravel055.png

Laravel 5.5 需要 7.0+ 版本的 PHP。想要了解当前 PHP 版本所带来的功能,可以参考我们为你提供的回顾。

Laravel 5.5 也将会是接下来的一个 LTS(长期支持)版本。 这就意味着它拥有两年修复以及三年的安全更新支持。Laravel 5.1 也是如此,不过它两年的错误修复支持将在今年结束。那么闲话少叙,让我们来看看这个新版本都提供了些什么吧。
/uploads/fox/14000420_0.jpeg

创建一个新的 Laravel 5.5 项目

我们可以通过运行以下命令安装 dev 版本:

/uploads/fox/14000420_2.png
如果您不想使用 Laravel 安装程序,还可以使用 Composer:

/uploads/fox/14000420_3.png
一旦我们访问了新设置的应用程序的主页,我们应该看到一个类似于我们以前的 Laravel 版本的欢迎页面。

在浏览器中渲染出邮件内容

我觉得这会是非常有用的东西。在 Laravel 之前的版本中,我们得实际去发送邮件,或者使用像 Mailtrap 这样的邮件客户端程序来测试邮件的布局,而这可不是啥好差事。时过境迁,有了 5.5 版本的 Laravel,局面得到改观,我们可以直接在浏览器调试邮件的布局显示。
达成此目的的捷径就是:给我们当前的工程创建一个新的可实际去发送的邮件模板:

我喜欢用 markdown 的方式来创建模板,里面会附上一些现成的内容。我们打开 web.php 文件,然后创建一个测试路由来查看 email 的布局:

/uploads/fox/14000420_5.png

routes/web.php


 通过浏览 /email 这个路由,我们就可以对 email 模板进行预览:

/uploads/fox/14000420_6.png
 
实际在幕后所发生的事情就是使用 Laravel 5.5, Mailable 类实现了拥有一个 render() 方法的 Renderable 协议。这个是 lluminate/Mail/Mailable.php 里面 render() 方法的实现:

/uploads/fox/14000420_7.jpeg

lluminate/Mail/Mailable.php


这个就是让获取一个视图成为可能的那个方法。我们尝试过返回一个类的示例,它并没有实现在我们的路由之中的那个 Renderable 协议,这时候会得到的是一个 UnexpectedValueException 被抛出来。

自定义邮件主体

当邮件使用 Markdown 时,Laravel 会提供默认主题。 但是,有些人可能希望在电子邮件模板中使用自定义样式进行品牌推广。
要使用特定可用的自定义主题,我们首先创建一个包含我们想要的样式的自定义 .css 文件:

然后,我们将该文件名指定为 Mailable 类中的一个属性:
/uploads/fox/14000420_9.png

app/Mail/Welcome.php


这样,电子邮件布局将基于我们在 custom.css 文件中定义的样式。 这种方法的好处是不同的邮件使用不同的主题。

Exception 辅助函数

Laravel 5.5 带来了两个辅助函数,他们能帮助我们编写更富表达能力的代码。这两个辅助程序就是 throw_if 和 throw_unless 方法。两者都需要三个参数,而且第三个参数都是可选的。

让我们来看一下这些异常的各种不同的实现:

/uploads/fox/14000420_11.png
使用 throw_if 方法,异常会在第一个参数计算出来为 true 的时候被抛出。
实现 throw_unless 方法跟我们上面所做的并没有不同, 唯一的差别就是异常只会在第一个参数计算出来为 false 的时候被抛出:
/uploads/fox/14000420_12.png
 
例子并不是最好的,但足够来体现我们的展示意图了。

介绍 migrate:fresh 命令

你可能发现自己处于需要重建数据库的境地。在以前的 Laravel 版本中,我们通过运行 php artisan migrate:refresh 命令来实现。migrate:refresh 命令基于针对每个迁移文件的 down 方法指定的内容回滚所有迁移,然后再次运行迁移:

/uploads/fox/14000420_14.jpeg
但你可能数次遇到这个命令的问题,尤其是使用外键约束或者你的某个迁移中存在定义得不太好的 down() 方法。如果发生这样的事情,我们多数时候会手工删除产生问题的表 —— (可能通过 CLI 或 GUI)。这正是 migrate:fresh 能帮助我们的地方。这个命令删除所有表,然后再次运行已经存在的迁移:

JSON 型错误堆栈跟踪

虽然不是一个很大的变化,但是在之前的 Laravel 版本中,每次我们在构建 API 出错时,我们在一个 API 客户端(如 Postman)看到的是 HTML 标记。 在 Laravel 5.5 中,如果发生错误,我们会得到一个 JSON 型堆栈跟踪,而不是 HTML 标记,这看起来更加简单易用:

/uploads/fox/14000420_16.jpeg

自动包发现

这些是我们遵循的步骤,以便在我们的 Laravel 项目中使用第三方软件包。

1、安装包
2、注册包服务的提供商
3、如果有任何 facade 的话就注册

步骤看起来很简单。

通过自动软件包可以发现,我们只需要一个软件包即可开始使用包。 但是请注意,只有在软件包提供程序配置了自动发现的软件包时,才能生效。

看看 Laravel Debugbar 包,它已经更新了 autodiscovery,我们来看看 composer.json 文件的 extra 段:

/uploads/fox/14000420_18.png
包的供应者会更新有 extra 段的 composer.json 文件,然后指定供应者和包的别名。

第三方组件的自动检测功能(Automatic Package Discovery)的另一个好处是移除了某个依赖项之后不会造成破坏。一般来说,就算我们卸载了某个包,还有包服务的供应者,以及围绕在 config/app.php 文件周围的假象,这在某些情况会导致问题的发生。

有了包自动发现,如果某个包被 Composer删除掉了,与这个包相关的东西都会被删除。

vendor 的改动:publish 命令

在之前的 Laravel 版本中,运行 vendor:publish 命令将发布包中所有的资源,并从框架本身中发布一些资源。发布的一些资源包括迁移、视图和配置。

使用 Laravel 5.5 之后,我们必须对运行此命令时要发布的内容有一些更明确的说明。如果我们运行在 php artisan vendor:publis 命令并不传递任何标志,我们将被提示选择提供商 vendor 或标签,以使其更容易仅发布我们想要的资源。见下面的截图:

/uploads/fox/14000420_20.jpeg
我们可以通过在执行 publish 命令时指定 --all 或 --provider 标志来绕过该提示:

前端预设的多样化

在 Laravel 5.3 和 5.4 中,我们默认有一些对 Vue 和 Bootstrap 辅助配置来帮助我们使用前端。在这个新版本中,React 已经被包含在这个组合中。但默认情况下 React 是不支持的。

其中有一个新的 artisan 命令来管理前端预设。这意味着我们只能使用我们想要使用的预设的辅助配置。但是并不是每个人都希望使用默认的前端预设 - 例如 Vue,Bootstrap 和 React - 并且可能在其他的前端上使用新的选项,也许是一个不同的前端框架。Laravel 已经考虑到了这一点了:

/uploads/fox/14000420_22.png

上述命令将删除任何现有的前端辅助配置。如果我们想使用 React 作为我们的前端,下面的命令会让我们得到一些 React 辅助配置:

/uploads/fox/14000420_23.png
下面是这些新命令执行时候的截屏:
/uploads/fox/14000420_24.jpeg

Whoops 归来

Laravel 5.5 中 Whoops 回归,更改了错误显示的方式。有了 Whoops !,每次在开发中出现错误时,我们都可以看到如截图所示的导致错误出现的代码行以及错误消息。

在我看来,新的处理器上错误消息的显示更加好看,对导致错误出现的代码行进行截屏使调试更容易:

Whoops 错误示例:

/uploads/fox/14000420_26.jpeg
 
另一件很酷的事情是,Whoops 可以直接在 IDE 或编辑器中打开引用的文件。此功能仅适用于在本地可以通过安装编辑器进行计算机访问的 PHP 源文件。要实现这一点,请转到 app / Exceptions / Handler.php 并添加此代码段:

/uploads/fox/14000420_27.jpeg

appExceptionsHandler.php


上面的代码片段通过添加以下行:$ handler-> setEditor('sublime')来覆盖基类中的whoopsHandler() 方法,这将导致链接在 Sublime Text 中打开。如果您使用其他编辑器,请访问此链接以查看支持的编辑器列表,以及如何添加自己的编辑器。 Mac 用户不要忘记下载 sublime 的 URL 协议,以使其工作。

自定义报告异常的方法

在以的版本的 Laravel 中,如果我们想以特定的方式自定义异常处理,我们必须把逻辑放在 Handler.php 文件的 report 方法中。下面是例子:
/uploads/fox/14000420_29.jpeg

app/Exceptions/Handler.php


假设我们有 50 个左右的自定义异常 —— 悲剧了。

而在 Laravel 5.5 中,如果想指定在异常抛出时做点什么,可以在异常内创建 report() 方法:
/uploads/fox/14000420_30.png
app/Exceptions/CustomException.php

模型工厂生成器

Laravel 5.5 带来了新的命令用于创建模型工厂。在我们写测试的时候,如果想生成一些假数据或某个对象的新实例,模型工厂就派上用场了。

为特定的类生成工作,需要运行这个命令:

如果我们浏览 database/factories,就会看到 PostFactory 类:
/uploads/fox/14000420_32.png

database/factories/PostFactory.php


我发现由于关系分离,这种方式显得更简洁。在以前版本的 Laravel 中,所有工厂都在 app/factries/ModelFactory.php 文件中。

返回验证数据

现在可以从验证器得到数据,并将这个数据传递给 create 方法。以前版本的 Laravel 中我们这样创建对象:
/uploads/fox/14000420_34.jpeg
Laravel 5.5 现在让我们直接从验证过的数据创建对象:

/uploads/fox/14000420_35.png
Laravel 5.5 中也可以直接在请求实例上调用 validate:
/uploads/fox/14000420_36.png
不过现在我们需要谨慎使用该方法来创建对象,因为验证方法未处理的属性都会没有值。为了克服这个问题,我们会向验证方法传入需要创建对象的所有属性,哪怕这些值不需要验证:
/uploads/fox/14000420_37.png
这样,数据会自动添加到允许请求的数据中,但不会接受任何验证规则的约束。

自定义验证规则

在以前版本的 Laravel 中可以使用 Validator::extend 方法来自定义验证规则。不过东西比较分散。我们有规则在 AppServiceProvider 文件中,而消息在 resources/lang/en/validation.php 文件中。看 Laravel 文档了解 Laravel 5.4 中如何实现。

Laravel 5.5 中我们有新的 artisan 命令来自定义验证规则。这个命令可生成一个实现了 Rule 约定的类。现在我们生成一个新的规则来看看生成的文件中都有什么:

在 app/Rules/CustomRule.php 中我们看到两个方法,passes 方法和 message 方法。passes 方法有两个参数,attribute 和 value,其返回值是布尔类型。不要疑惑,$attribute 是用于验证的域,而 $value 是那个属性的值。

下面的示例中,假设我们不希望应用中使用某个名字,那么 我们的 Rule 看起来像这样:

/uploads/fox/14000420_39.jpeg

app/Rules/CustomRule.php


然后使用新规则来验证我们的 username 属性:
/uploads/fox/14000420_40.png

app/Rules/CustomRule.php


看看 Taylor Otwell 发表的文章,它深入研究了如何在新版本的 Laravel 中自定义验证。

集合中的 DD 和 Dump 支持

集合现在拥有一个 dump() 方法以及一个 dd() 方法。在以前的 Laravel 版本中,当调试集合时,我们会为一个集合分配一个变量,然后在更改集合时继续转储变量。在 Laravel 5.5 中不再是这样的了,因为我们现在可以直接在集合上调用 dd() 或 dump() 接口,从而使得调试更容易。

假定我们有一个 posts 的集合,其中通过一系列变换得到,我们希望在逐步检查集合中的数据,那么可以这样做:

/uploads/fox/14000420_42.png
同时输出如下:
/uploads/fox/14000420_43.jpeg
这样可以很方便地在逐步检查集合的内容。但是请注意,在集合上调用 dump() 和调用 dd() 是有区别的。dump() 输出结果,然后继续处理;但 dd() 则会立即停止进程并转储结果(dd 代表 dump & die)。曾经我们每一步都在集合上调用 dd(),我们只会在得到我们首次在集合上调用 dd() 的结果。考虑下这个:

/uploads/fox/14000420_44.png
输出结果是不同的:
/uploads/fox/14000420_45.jpeg
Pivot 表中多对多关系的类型转换

通常,可以在 Model 上声明一个 casts 属性,该属性定义了如何保存或读取指定属性。假设我们有一个 Post Model,在它的值域中,我们希望在读取和写入时将其中一个字段序列化为 JSON 格式,那么下面的代码片段将帮助我们实现该功能:

/uploads/fox/14000420_46.png
他们甚至实现了在 Laravel 5.4 中建立多对多关系的用户自定义 pivot 转换,但这仅限于读取数据。如果我们要对数据执行写操作,我们在最终保存数据前必须先手动转换其属性值。因为 EloquentModel 和 EloquentRelationshipPivot 类的 $casts 属性将通过同样的行为使 attach、sync、save 方法在 pivot model 中可用,但情况可能就不一样了。

自定义 Blade::if() 指令

Blade 模板中冗长重复的检查使得模板看起来很丑陋。好在现在可以从模板中抽出这些重复检查,这就能使我们的模板看起来更整洁、更易读。检查语句如下:
/uploads/fox/14000420_48.png
可以被替换为:
/uploads/fox/14000420_49.png
创建自定义 blade 指令的逻辑主要位于 AppServiceProvider 类的 boot 方法中:
/uploads/fox/14000420_50.jpeg

app/Providers/AppServiceProvider.php


一些检查语句可能需要将参数传递给某种方法。在这种情况下,当我们遇到一个自定义 blade 指令时,我们会将一个参数传递给闭包。
使用上述条件作为示例,我们看到我们需要 $user->id 传递到 isFollowing() 方法中。要创建一个自定义 blade 指令,它将 $user-> id 作为参数:
/uploads/fox/14000420_51.png
之后就可以在我们的模板中使用新的指令了:
/uploads/fox/14000420_52.png

在内核中自动注册新的 Artisan 命令

我们通常运行命令 php artisam make:command command-name 来创建新的 artisan 命令。这之后,我们使用该命令声明我们在类中的签名,然后转到内核并手动注册该命令。

在内核中注册新的命令将不再是必需的了。在 app/Console/kernel.php 文件中,我们有一个新的方法,支持在命令目录中超查找,并将所有文件路径转换为命名空间的路径:
/uploads/fox/14000420_54.png
假设我们引用了一个尚未在内核中注册的命令,那么 commands() 方法将自动解析该命令。

新的路由方法

这并不是一个很大的功能,但是我们现在有两种额外的路由方法:
/uploads/fox/14000420_56.png
第一条路由将 welcom 视图映射到 /welcome 路由上,而第二条路由将重定向所有发给 /home 的请求到 /dashboard 上。

引入 Laravel Horizon

这是一个全新的 Laravel 包,它为 Laravel Redis 队列提供了一个面板以及代码驱动的配置系统:
/uploads/fox/14000420_58.jpeg
Horizon 提供对队列工作负载、近期作业、失败作业、作业重试、吞吐量和运行时指标以及进程计数的实时分析。
Horizon 的一些功能包括:

1、作业的高层分析 - 类似每分钟的作业数目,过去一小时的作业状况等
2、作业和专门针对排队的分析
3、标签和监控 - 支持向作业添加标签,并监视某些标签
4、队列均衡策略 - Horizon 可以根据这些队列的工作负载情况自动均衡队列中的工作进程
 
参见 Taylor Otwell的文章,其中深入分析了如何配置 Horizon 及 Horizon 所包含的所有功能。我们还将推出一篇专门介绍的 Horizon 撰文,敬请关注。

新的数据库迁移 trait

这就是 RefreshDatabase trait。有些人可能会怀疑我们是否真的需要这个,但这样做是有道理的。最初我们拥有 DatabaseMigrations 和 DatabaseTransactions 两个 trait。

在我们的测试中使用 DatabaseMigrations trait 可确保在每次测试之前和之后运行的迁移正确,而 DatabaseTransactions trait 确保在运行每个测试后数据库恢复到初始状态。

RefreshDatabase trait 将通过在测试开始时迁移数据库一次,然后在之后运行每个测试时使用事务,从而实现这两种功能。这样做的好处是我们不必为每个测试重新迁移数据库,这意味着更快的测试。

结论

你可以看到,我们有很多令人兴奋的新东西。 更多的功能还在推出,所以请关注这篇文章,我们将保持更新。 在下面的评论部分留下您的想法和建议,不要忘记与 Laravel 爱好者分享这篇文章!

评论