专栏首页PHP 开发[译]Laravel 5.0 之 ValidatesWhenResolved

[译]Laravel 5.0 之 ValidatesWhenResolved

本文译自 Matt Stauffer 的系列文章.


在创建 FormRequest 的时候, Taylor(译注: Laravel 框架的作者) 还编写了一个接口 (ValidatesWhenResolved) 和一个 trait (ValidatesWhenResolvedTrait), 都是用于对控制器方法进行校验的. 这种校验会在IOC 容器对该方法的依赖项解析成功时调用.

老实说, 我目前还没有写出一个在 FormRequests 类之外的应用场景来使用这两个东西的实例. 但我还是想写一篇文档来介绍它们, 希望有比我更聪明的人来找出它们在实际项目中可能的应用场景.

所以, 如果你读过我的上一篇文章, 你已经了解了 FormRequest 对象, 通过 IOC 的依赖注入机制注入到方法, 可以取消相关方法的执行. 假如表单提交的数据不能通过校验, 与该表单对应的 POST route 会被负责校验它的 FormRequest 类取消执行.

这带来的一个结果就是: "触发 IOC 容器的 FormRequest 调用校验方法" 这个操作可以被分离为一个单独的接口, 名为 ValidatesWhenResolved. 借助这一点, 我们也可以创建类似 FormRequest 的类, 在执行控制器方法 (理论上非控制器也可以) 之前对请求进行拦截, 并决定它能否通过校验.

说明: 如果一个请求校验失败的话, 路由或方法其实没有真正取消. FormRequest 只是抛出了一个 HTTP 异常, 该异常随后以 JSON 格式返回, 或者被重定向到处理异常的页面. 理论上来说, 你不实现这个接口, 而只是简单地在控制器的构造函数中进行校验并抛出异常也是一样的. 但是借助这个接口, 我们可以保持代码清洁, 并且可以在一个命名的方法中来执行校验.

接口

在本文写作的时候, 该接口的签名是这样的:

namespace Illuminate\Contracts\Validation;

use Illuminate\Contracts\Container\Container;

interface ValidatesWhenResolved {

    /**
     * 对指定的类实例进行校验
     *
     * @return void
     */
    public function validate();

}

通过该签名可知, 实现这个接口只需要实现一个方法 validate(). 事实上, 对于实现这个方法的类, 我们只需要知道一点, 就是当 IOC 容器解析到它的时候, 会调用 validate() 这个方法. 接下来我们就来创建一个并非 FormRequest 扩展类但是却实现了这个接口的类:

在控制器中不使用 FormRequest 进行校验

// app/Http/Controllers/ValidatedController.php

namespace App\Http\Controllers;

use App\Random\RandomAccess;
use Illuminate\Routing\Controller;
use Response;

class ValidatedController extends Controller
{
    public function random(RandomAccess $ram)
    {
        return Response::make('You made it!');
    }
}

上面是一个简单的控制器. 有了路由之后, 我们来创建一个不继承 FormRequest 的验证类:

// app/Random/RandomAccess.php
namespace App\Random;

use Exception;
use Illuminate\Contracts\Validation\ValidatesWhenResolved;
use Illuminate\Http\Request;

class RandomAccess implements ValidatesWhenResolved
{
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function validate()
    {
        // Test for an even vs. odd remote port
        if (($this->request->server->get('REMOTE_PORT') / 2) % 2 > 0)
        {
            throw new Exception("WE DON'T LIKE ODD REMOTE PORTS");
        }
    }
}

现在控制器方法就被拦截并且随机抛出异常 (取决于请求访问的端口是奇数还是偶数, 这恐怕是有史以来最没实用价值的一个例子了, 哈哈).

如你所见, 这里没有用到什么神奇的东西, validate() 方法是否返回 true 或者 false 并不重要. 你当然可以通过 ValidatesWhenResolvedTrait 这个 trait 来实现 FormRequest 中的 failedValidation() 的部分流程, 而在上面的例子中, 只需要抛出异常就可以了.

在控制器之外使用 FormRequest 风格的验证

在控制器之外也可以使用这些手段, 比如在 FormRequest 风格的验证中使用 ValidatesWhenResolvedTrait. 但我暂时没有找到合适的用例, 所以我先简单地略过这部分. 你可以自己尝试... 但是我想不出有什么理由值得这样去做, 呵呵.

真实案例

你肯定不会像上面的例子里那样去随机抛出异常. 本文探讨的这些新特性最终看起来有点像以前的 route filters. 但我还是怀疑它们在实际中能有多少应用场景. 不管怎么说, 要是你想给你的控制器注入什么东西的话, 或者可以让它实现 ValidatesWhenResolved 接口或者使用 ValidatesWhenResolvedTrait, 这样它就能通过注入进行自动校验, 不用额外去调用一个校验方法了.

结束语

你可以认为这篇文章的目的就是为了钓鱼, 看看能否找到对这个新特性的实际应用场景. 假如你有什么想法, 可以通过 Twitter 与 @stauffermatt 进行讨论.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • CentOS 7 开启 BBR 加速

    Google 在 2016年9月份开源了他们的优化网络拥堵算法BBR,最新版本的 Linux内核(4.9-rc8)中已经集成了该算法。 对于TCP单边加速,并非...

    小李刀刀
  • 前端构建工具 Gulp.js 上手实例

    在软件开发中使用自动化构建工具的好处是显而易见的。通过工具自动化运行大量单调乏味、重复性的任务,比如图像压缩、文件合并、代码压缩、单元测试等等,可以为开发者节约...

    小李刀刀
  • [译]Laravel 5.0 之 表单验证类 (Form Requests)

    本文译自 Matt Stauffer 的系列文章. ---- 让人头痛的表单验证 只要你曾经在使用 Laravel 框架的过程中试图找到有关用户输入验证的最佳实...

    小李刀刀
  • 量子计算应对大数据挑战: 中国科大首次实现量子机器学习算法

    中国科学技术大学潘建伟教授及其同事陆朝阳、刘乃乐等组成的研究团队在国际上首次实现量子机器学习算法。日前,国际权威物理学期刊《物理评论快报》发表了这一论文[Phy...

    CSDN技术头条
  • beagle MONO 应用的desktop search

          beagle是linux的desktop search软件,跟winows下的google desktop search类似的东西,它可以搜索各种各...

    张善友
  • 如何在 CentOS 8 上安装 Nginx

    Nginx 发音”engine x“,它是一个开源,高性能的 HTTP 和反向代理服务器,用于处理 Internet 上一些大型网站的负载。它可以被用作一个独立...

    雪梦科技
  • Docker Hub 仓库使用,及搭建 Docker Registry

    目前 Docker 官方维护了一个公共仓库 Docker Hub,其中已经包括了数量超过 15,000 的镜像。大部分需求都可以通过在 Docker Hub 中...

    搜云库
  • 【深度解密】量子机器学习的研究进展

    作者是来自英国布里斯托大学的量子工程中心研究员,布里斯托大学在量子力学和量子计算方面有很强的建树,诺贝尔物理学奖获得者、量子力学的奠基者之一保罗·狄拉克,中国科...

    新智元
  • nginx: [emerg] unknown directive “ ” in /usr/local/nginx/nginx.conf.conf:xx报错处理

    当我们在修改Nginx的配置文件,然后加载配置文件./nginx -s reload 报错类似的错误,

    Arebirth
  • [Java面试六]SpringMVC总结以及在面试中的一些问题.

    一枝花算不算浪漫

扫码关注云+社区

领取腾讯云代金券