ThinkPHP5 验证器的具体使用


Posted in PHP onMay 31, 2018

前言:

我们在做API开发的时候,我们会接受客户端传来的参数,大家都知道这个参数是不可信的,我们后端开发人员必须对这个参数进行验证。我在之前的开发中只是知道tp5的验证器,并不知道他的用途,因为之前的开发验证,往往都是基于模型字段进行的验证。而验证器更适用与API开发,今天就简单讲下验证器的使用

目录:

  1. 创建验证器
  2. 书写单独验证器
  3. 调用验证

1.创建验证器

首先我们需要一个文件夹来存放我们的验证器,我们在模块下创建一个同控制器平级的文件夹,取名为validate

ThinkPHP5 验证器的具体使用

然后我们就可以来建立验证器了,我们只需要创建一个类,继承tp5的validate类就可以了。

但是熟悉面向对象思想的朋友一定知道,当我们需要一个方法每个验证器都要用到,但是又不去修改tp5的源码时。我们就多写一个类来作为我们的基类。所有的验证器都继承这个基类,然后这个基类再去继承tp5的validate类。

这里我们把他取名为baseValidate

ThinkPHP5 验证器的具体使用

那么现在再创建一个正儿八经的验证器了。举个例子:

namespace app\index\validate;

use think\Validate;

class User extends Validate
{
  protected $rule = [
    'name' => 'require|max:25',
    'email' => 'email',
  ];

}

再到控制器或者模型中去实例化再调用

//虚拟一组数据,实际开发中是接受用户传递的数据
$data = [
  'name'=>'thinkphp',
  'email'=>'thinkphp@qq.com'
];

$validate = Loader::validate('User');

if(!$validate->check($data)){
  dump($validate->getError());
}

这样一个验证器的应用就写好了。我们来看看有没有什么可以简化的地方。

  1. 首先需要被验证的数据是我们从客户端那接受过来的那么,第一步接受数据
  2. 然后我们要对数据进行验证,如果验证不通过,返回错误信息

这两部是每次接口被请求都是要做的。那么我们就想把这个封装到BaseValidate中去

namespace app\home\validate;
use think\Exception;
use think\Request;
use think\Validate;
class BaseValidate extends Validate
{
  public function goCheck($data='')
  {
    //实例化请求对象
    $requestObj=Request::instance();
    //如果传入为空则获取请求里的参数
    empty($data)&&$data=$requestObj->param();
    if ($this->check($data)) {
      //如果验证通过了
      return true;
    }else{
      //如果验证没通过
      $error=$this->getError();
      //抛出异常
      throw new Exception($error);
    }
  }
}

这个goCheck方法封装好后,有人可能会问,这个验证规则在哪里呢?

2. 书写单独验证器

之前有说过BaseValidate是用来被继承的,那么真正的验证器,我们还没有开始写。规则就制定到这个验证器中。为了更深入的理解,这里举例子顺便使用了自定义验证 规则。其实tp写好了的验证规则应该很够用了

我们就拿最常接受的数据来举例子,那就是 id 同常这个id就代表了我们数据库中某条数据的id,这个id我们往往设计为无符号自动递增的主键,翻译成人话就是正整数。那么如果客户传来的参数是负数或者小数那么就不应该通过验证。

我们根据上述需求,我们来创建一个验证器。位置还是跟之前的一样在validate文件夹下

ThinkPHP5 验证器的具体使用

取名为IdMustBePositiveInt.php(名字有点长,不过好在望文知意)

首先肯定是要继承我们的基础验证器

class IdMustBePositiveInt extends BaseValidate

然后制定规则,为一个固定的成员变量赋值

protected $rule = [
  //require是内置规则,而tp5并没有正整数的规则,所以下面这个positiveInt使用自定义的规则
    'id' => 'require|positiveInt'
  ];

那么自定义规则怎么干呢,其实也简单。定义一个被保护的方法

//系统会自动传入几个参数 第一个是 要验证的值,第二个是规则,自己可以规定规则内容或者不写,第三个是最初传入的data。其实不只这三个参数,想了解详细的可以看看文档
 protected function positiveInt($value, $rule='', $data)
  {
    if (is_int(($value+0))&&($value+0)>0) {
      return true;
    }else{
      return 'id必须为正整数';
    }
  }

!!注意:这里如果判断失败:返回的不是false 返回的是错误信息。

3. 调用验证

根据我们之前的封装,我们需要达到的效果就是接受参数,验证参数一体。那么现在我们如何调用验证呢

厉害的来了,我们还是以id为例

public function test($id)
  {
    //在控制器中直接调用写上这行代码就搞定验证了
    (new IdMustBePositiveInt)->goCheck();
  }
  1. 就这样的一句代码,直接搞定验证。当我们实例化id验证器,调用它父类的goCheck方法。
  2. goCheck方法会接受参数,并且将参数传入validate对象上check方法
  3. 就会去匹配我们在id验证器中$rule中规定的require规则和我们自定义的规则。
  4. 如果都通过就会返回true
  5. 如果其中一条不匹配则会抛出异常

这次只举了id为例子,虽然看上去比直接写独立验证麻烦很多,但是大家仔细想想,这个验证规则其实在很多地方都是一样的,比如密码验证规则,用户名验证规则等,当这个项目写完了。你已经完成了很多验证器。其实在下个项目中还可以继续套用的哦

TP5验证规则使用

①静态调用(使用内置的规则验证单个数据,返回值为布尔值)

// 日期格式验证
Validate::dateFormat('2016-03-09','Y-m-d'); // true
// 验证是否有效的日期
Validate::is('2016-06-03','date'); // true
// 验证是否有效邮箱地址
Validate::is('thinkphp@qq.com','email'); // true
// 验证是否在某个范围
Validate::in('a',['a','b','c']); // true
// 验证是否大于某个值
Validate::gt(10,8); // true
// 正则验证
Validate::regex(100,'\d+'); // true

②模型验证(在模型中的验证方式)

$User = new User;
$result = $User->validate(
  [
    'name' => 'require|max:25',
    'email'  => 'email',
  ],
  [
    'name.require' => '名称必须',
    'name.max'   => '名称最多不能超过25个字符',
    'email'    => '邮箱格式错误',
  ]
)->save($data);
if(false === $result){
  // 验证失败 输出错误信息
  dump($User->getError());
}

③控制器验证(控制器中进行验证)

如果你需要在控制器中进行验证,并且继承了\think\Controller的话,可以调用控制器类提供的validate方法进行验证,如下:

$result = $this->validate(
  [
    'name' => 'thinkphp',
    'email' => 'thinkphp@qq.com',
  ],
  [
    'name' => 'require|max:25',
    'email'  => 'email',
  ]);
if(true !== $result){
  // 验证失败 输出错误信息
  dump($result);
}

控制器中的验证代码可以简化为:

$result = $this->validate($data,'User');
if(true !== $result){
  // 验证失败 输出错误信息
  dump($result);
}

如果要使用场景,可以使用:

$result = $this->validate($data,'User.edit');
if(true !== $result){
  // 验证失败 输出错误信息
  dump($result);
}

在validate方法中还支持做一些前置的操作回调,使用方式如下:

$result = $this->validate($data,'User.edit',[],[$this,'some']);
if(true !== $result){
  // 验证失败 输出错误信息
  dump($result);
}

好了,本次tp5验证器的介绍了就写到这里了,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP无限分类的类
Jan 02 PHP
PHP insert语法详解
Jun 07 PHP
一步一步学习PHP(2)――PHP类型
Feb 15 PHP
php中将网址转换为超链接的函数
Sep 02 PHP
php实现天干地支计算器示例
Mar 14 PHP
ThinkPHP里用U方法调用js文件实例
Jun 18 PHP
php时间计算相关问题小结
May 09 PHP
PHP is_array() 检测变量是否是数组的实现方法
Jun 13 PHP
php中上传文件的的解决方案
Sep 25 PHP
PHP时间日期增减操作示例【date strtotime实现加一天、加一月等操作】
Dec 21 PHP
phpinfo无法显示的原因及解决办法
Feb 15 PHP
JS中彻底删除JSON对象组成的数组中的元素
Sep 22 PHP
php 截取中英文混合字符串的方法
May 31 #PHP
PHP封装curl的调用接口及常用函数详解
May 31 #PHP
PHP通过curl获取接口URL的数据方法
May 31 #PHP
php获得刚插入数据的id 的几种方法总结
May 31 #PHP
PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能
May 31 #PHP
PHP实现可精确验证身份证号码的工具类示例
May 31 #PHP
JSON PHP中,Json字符串反序列化成对象/数组的方法
May 31 #PHP
You might like
PHPShop存在多个安全漏洞
2006/10/09 PHP
mysql_num_rows VS COUNT 效率问题分析
2011/04/23 PHP
JavaScript delete操作符应用实例
2009/01/13 Javascript
js 对联广告、漂浮广告封装类(IE,FF,Opera,Safari,Chrome
2009/11/26 Javascript
Microsfot .NET Framework4.0框架 安装失败的解决方法
2013/08/14 Javascript
Knockout visible绑定使用方法
2013/11/15 Javascript
node.js中的buffer.write方法使用说明
2014/12/10 Javascript
基于jQuery通过jQuery.form.js插件使用ajax提交form表单
2015/08/17 Javascript
ANGULARJS中使用JQUERY分页控件
2015/09/16 Javascript
js自定义回调函数
2015/12/13 Javascript
js封装tab标签页实例分享
2016/12/19 Javascript
vue2.0中goods选购栏滚动算法的实现代码
2017/05/17 Javascript
微信小程序实现点击按钮修改view标签背景颜色功能示例【附demo源码下载】
2017/12/06 Javascript
vue axios请求超时的正确处理方法
2018/04/02 Javascript
JavaScript中为事件指定处理程序的五种方式分析
2018/07/27 Javascript
解决layui追加或者动态修改的表单元素“没效果”的问题
2019/09/18 Javascript
微信小程序使用自定义组件导航实现当前页面高亮
2020/01/02 Javascript
原生JS实现九宫格抽奖
2020/09/13 Javascript
Python 命令行非阻塞输入的小例子
2013/09/27 Python
Python函数中*args和**kwargs来传递变长参数的用法
2016/01/26 Python
Python Pexpect库的简单使用方法
2019/01/29 Python
Python3.4学习笔记之列表、数组操作示例
2019/03/01 Python
pycharm中使用request和Pytest进行接口测试的方法
2020/07/31 Python
python 生成正态分布数据,并绘图和解析
2020/12/21 Python
浅谈three.js中的needsUpdate的应用
2012/11/12 HTML / CSS
amazeui时间组件的实现示例
2020/08/18 HTML / CSS
Europcar德国:全球汽车租赁领域的领导者
2018/08/15 全球购物
什么是事务?为什么需要事务?
2012/01/09 面试题
.NET常见笔试题集
2012/12/01 面试题
大学生学习2014年全国两会心得体会
2014/03/12 职场文书
房屋转让协议书
2014/04/11 职场文书
村班子对照检查材料
2014/08/18 职场文书
退学证明范本3篇
2014/10/29 职场文书
java中用float时,数字后面加f,这样是为什么你知道吗
2021/09/04 Java/Android
win10以太网连接不上怎么办?Win10连接以太网详细教程
2022/04/08 数码科技
多台电脑共享文件怎么设置?多台电脑共享文件操作教程
2022/04/08 数码科技