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 相关文章推荐
常用表单验证类,有了这个,一般的验证就都齐了。
Dec 06 PHP
php 图像函数大举例(非原创)
Jun 20 PHP
PHP中对用户身份认证实现两种方法
Jun 04 PHP
有关PHP中MVC的开发经验分享
May 17 PHP
又一个PHP实现的冒泡排序算法分享
Aug 21 PHP
PHP解析RSS的方法
Mar 05 PHP
Laravel执行migrate命令提示:No such file or directory的解决方法
Mar 16 PHP
PHP Yaf框架的简单安装使用教程(推荐)
Jun 08 PHP
简单的自定义php模板引擎
Aug 26 PHP
PHP实现判断数组是一维、二维或几维的方法
Feb 06 PHP
PHP7.1实现的AES与RSA加密操作示例
Jun 15 PHP
PHP中用Trait封装单例模式的实现
Dec 18 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
全世界最小的php网页木马一枚 附PHP木马的防范方法
2009/10/09 PHP
ExtJS与PHP、MySQL实现存储的方法
2010/04/02 PHP
mysql 查询指定日期时间内sql语句实现原理与代码
2012/12/16 PHP
PHP设计模式之装饰器模式实例详解
2018/02/07 PHP
js资料toString 方法
2007/03/13 Javascript
JavaScript入门教程(11) js事件处理
2009/01/31 Javascript
jQuery Validation实例代码 让验证变得如此容易
2010/10/18 Javascript
JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(六)
2012/04/07 Javascript
JS 模态对话框和非模态对话框操作技巧汇总
2013/04/15 Javascript
jquery通过ajax加载一段文本内容的方法
2015/01/15 Javascript
JS实现网页背景颜色与select框中颜色同时变化的方法
2015/02/27 Javascript
原生javascript实现解析XML文档与字符串
2016/03/01 Javascript
javaScript如何跳出多重循环break、continue
2016/09/01 Javascript
详解Vue路由开启keep-alive时的注意点
2017/06/20 Javascript
vue+vux实现移动端文件上传样式
2017/07/28 Javascript
浅谈vue-props的default写不写有什么区别
2020/08/09 Javascript
Javascript异步流程控制之串行执行详解
2020/09/27 Javascript
[01:24:09]Ti4 冒泡赛第二轮DK vs C9 1
2014/07/14 DOTA
python调用短信猫控件实现发短信功能实例
2014/07/04 Python
Python中字典和JSON互转操作实例
2015/01/19 Python
CentOS 6.X系统下升级Python2.6到Python2.7 的方法
2016/10/12 Python
python matplotlib画图实例代码分享
2017/12/27 Python
Python基于Floyd算法求解最短路径距离问题实例详解
2018/05/16 Python
儿童python练习实例
2018/05/27 Python
python Pillow图像处理方法汇总
2019/10/16 Python
Python Django form 组件动态从数据库取choices数据实例
2020/05/19 Python
python之语音识别speech模块
2020/09/09 Python
俄罗斯披萨、寿司和面食送货到家服务:2 Берега
2019/12/15 全球购物
领导检查欢迎词
2014/01/14 职场文书
篝火晚会策划方案
2014/05/16 职场文书
乡镇干部先进性教育活动个人整改措施
2014/09/16 职场文书
2014年幼儿园后勤工作总结
2014/11/10 职场文书
离婚律师函范本
2015/05/27 职场文书
公务员廉洁从政心得体会
2016/01/19 职场文书
粗暴解决CUDA out of memory的问题
2021/05/22 Python
Python中使用Opencv开发停车位计数器功能
2022/04/04 Python