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 相关文章推荐
vBulletin HACK----显示话题大小和打开新窗口于论坛索引页
Oct 09 PHP
php xml文件操作代码(一)
Mar 20 PHP
PHP utf-8编码问题,utf8编码,数据库乱码,页面显示输出乱码
Apr 08 PHP
PHP中模拟处理HTTP PUT请求的例子
Jul 22 PHP
PHP实现上传多文件示例代码
Feb 20 PHP
PHP使用PHPExcel实现批量上传到数据库的方法
Jun 08 PHP
php实现推荐功能的简单实例
Sep 29 PHP
Laravel find in set排序实例
Oct 09 PHP
laravel自定义分页的实现案例offset()和limit()
Oct 15 PHP
解决windows上php xdebug 无法调试的问题
Feb 19 PHP
PHP加MySQL消息队列深入理解
Feb 27 PHP
PHP7新增函数
Mar 09 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
PHPMailer安装方法及简单实例
2008/11/25 PHP
给初学者的30条PHP最佳实践(荒野无灯)
2011/08/02 PHP
PHP无法访问远程mysql的问题分析及解决
2013/05/16 PHP
php 强制下载文件实现代码
2013/10/28 PHP
php常用文件操作函数汇总
2014/11/22 PHP
如何利用预加载优化Laravel Model查询详解
2017/08/11 PHP
php创建类并调用的实例方法
2019/09/25 PHP
jQuery对象和DOM对象使用说明
2010/06/25 Javascript
jQuery的写法不同导致的兼容性问题的解决方法
2010/07/29 Javascript
jquery text(),val(),html()方法区别总结
2013/11/04 Javascript
Javascript判断文件是否存在(客户端/服务器端)
2014/09/16 Javascript
js实现文字超出部分用省略号代替实例代码
2016/09/01 Javascript
ThinkPHP+jquery实现“加载更多”功能代码
2017/03/11 Javascript
ElementUI之Message功能拓展详解
2019/10/18 Javascript
JS将指定的某个字符全部转换为其他字符实例代码
2020/10/13 Javascript
[03:09]2014DOTA2国际邀请赛 赛场上的美丽风景线 中国Coser也爱DOTA2
2014/07/20 DOTA
跟老齐学Python之让人欢喜让人忧的迭代
2014/10/02 Python
详解Django中间件的5种自定义方法
2018/07/26 Python
Python 类方法和实例方法(@classmethod),静态方法(@staticmethod)原理与用法分析
2019/09/20 Python
基于Django统计博客文章阅读量
2019/10/29 Python
Python文件操作基础流程解析
2020/03/19 Python
python 两种方法修改文件的创建时间、修改时间、访问时间
2020/09/26 Python
python RSA加密的示例
2020/12/09 Python
IE矩阵Matrix滤镜旋转与缩放及如何结合transform
2012/11/29 HTML / CSS
亚马逊中国官方网站:amazon.cn
2017/05/25 全球购物
女士和男士时尚鞋在线购物:Shoespie
2019/02/28 全球购物
出纳的岗位职责
2013/11/09 职场文书
2014升学宴答谢词
2014/01/26 职场文书
大学生自我评价范文分享
2014/02/21 职场文书
2014学习全国两会精神心得体会2000字
2014/03/11 职场文书
业务员工作态度散漫检讨书
2014/11/02 职场文书
2015年三八妇女节活动总结
2015/02/06 职场文书
认真学习保证书
2015/02/26 职场文书
浪漫的婚礼主持词
2015/06/30 职场文书
公司酒会主持词
2015/07/02 职场文书
使用css样式设计一个简单的html登陆界面的实现
2021/03/30 HTML / CSS