[译]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 IlluminateContractsValidation;
use IlluminateContractsContainerContainer;
interface ValidatesWhenResolved {
/**
* 对指定的类实例进行校验
*
* @return void
*/
public function validate();
}
通过该签名可知, 实现这个接口只需要实现一个方法 validate()
. 事实上, 对于实现这个方法的类, 我们只需要知道一点, 就是当 IOC 容器解析到它的时候, 会调用 validate()
这个方法. 接下来我们就来创建一个并非 FormRequest 扩展类但是却实现了这个接口的类:
在控制器中不使用 FormRequest 进行校验
// app/Http/Controllers/ValidatedController.php
namespace AppHttpControllers;
use AppRandomRandomAccess;
use IlluminateRoutingController;
use Response;
class ValidatedController extends Controller
{
public function random(RandomAccess $ram)
{
return Response::make('You made it!');
}
}
上面是一个简单的控制器. 有了路由之后, 我们来创建一个不继承 FormRequest 的验证类:
// app/Random/RandomAccess.php
namespace AppRandom;
use Exception;
use IlluminateContractsValidationValidatesWhenResolved;
use IlluminateHttpRequest;
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 进行讨论.
- 分享一波关于做 Kaggle 比赛,Jdata,天池的经验,看完我这篇就够了。
- system表空间不足的问题分析(r6笔记第66天)
- 挑战数据结构和算法面试题——最大间隔
- 一则orabbix报警的分析(r6笔记第65天)
- 中科院计算所开源深度文本匹配开源工具 MatchZoo
- 简单易学的机器学习算法——线性回归(1)
- 当主键碰到NULL(r6笔记第64天)
- 记一次dg故障的处理总结(r6笔记第63天)
- Java企业面试——Javaweb
- Linux下/var/spool/clientmqueue空间不足的解决(r6笔记第81天)
- Pytorch 0.3发布:实现多方面提速,增加对ONNX支持 | 快讯
- 基于DB time的调优分析 (r6笔记第79天)
- 通过shell脚本抓取awr报告中的问题sql(r6笔记第78天)
- Tomcat 快速入门
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC
- CentOS7下编译安装libmodbus库
- 你还以为使用 StringBuffer 就万事大吉了?
- Windows10中VS2017环境下使用libmodbus库Modbus TCP读取设备的数据
- 记一次生产服务器进程突然消失问题排查!
- 0812-7.1.3-如何使用Ranger给HBase授权
- Redis集群方案对比:Codis、Twemproxy、Redis Cluster
- 这就是你日日夜夜想要的docker!!!---------Docker镜像制作与私有仓库建立
- 排障集锦:九九八十一难之第十八难!-----System has not been booted with systemd as init system (PID 1). Can‘t operat
- 深入了解 Flex 属性
- 如何设计一个安全的短信接口?
- ERROR Shell:396 - Failed to locate the winutils binary in the hadoop binary path java.io.IOE...
- Windows 安装配置 PySpark 开发环境(详细步骤+原理分析)
- 安利三个关于Python字符串格式化进阶知识
- TCP/IP学习笔记1——协议分层
- 用Python爬取淘宝4403条大裤衩数据进行分析,终于找到可以入手的那一条