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 17 PHP
PHP中操作ini配置文件的方法
Apr 25 PHP
深入解析php之sphinx
May 15 PHP
PHP基于CURL进行POST数据上传实例
Nov 10 PHP
Yii框架在页面输出执行sql语句以方便调试的实现方法
Dec 24 PHP
浅谈PHP中output_buffering
Jul 13 PHP
php 数组字符串搜索array_search技巧
Jul 05 PHP
PHP从二维数组得到N层分类树的实现代码
Oct 11 PHP
php 二维数组时间排序实现代码
Nov 19 PHP
PHP递归的三种常用方式
Feb 28 PHP
PHP实现笛卡尔积算法的实例讲解
Dec 22 PHP
php中try catch捕获异常实例详解
Aug 06 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插入排序实现代码
2013/04/04 PHP
Linux下安装Memcached服务器和客户端与PHP使用示例
2019/04/15 PHP
js对列表中第一个值处理与jsp页面对列表中第一个值处理的区别详解
2013/11/05 Javascript
JS随机漂浮广告代码具体实例
2013/11/19 Javascript
限制上传文件大小和格式的jQuery插件实例
2015/01/24 Javascript
bootstrap weebox 支持ajax的模态弹出框
2017/02/23 Javascript
基于jQuery中ajax的相关方法汇总(必看篇)
2017/11/08 jQuery
JS函数内部属性之arguments和this实例解析
2018/10/07 Javascript
vue-cli中使用高德地图的方法示例
2019/03/28 Javascript
antd 表格列宽自适应方法以及错误处理操作
2020/10/27 Javascript
跟老齐学Python之有容乃大的list(1)
2014/09/14 Python
Python实现的监测服务器硬盘使用率脚本分享
2014/11/07 Python
Django中使用locals()函数的技巧
2015/07/16 Python
利用python批量检查网站的可用性
2016/09/09 Python
Python实现备份MySQL数据库的方法示例
2018/01/11 Python
Python中的默认参数实例分析
2018/01/29 Python
python编程测试电脑开启最大线程数实例代码
2018/02/09 Python
python使用插值法画出平滑曲线
2018/12/15 Python
python flask几分钟实现web服务的例子
2019/07/26 Python
解决pandas展示数据输出时列名不能对齐的问题
2019/11/18 Python
Tensorflow限制CPU个数实例
2020/02/06 Python
python利用datetime模块计算程序运行时间问题
2020/02/20 Python
pycharm新建Vue项目的方法步骤(图文)
2020/03/04 Python
python中元组的用法整理
2020/06/15 Python
PyCharm最新激活码(2020/10/27全网最新)
2020/10/27 Python
原装进口全世界:天猫国际
2016/08/03 全球购物
Keds官方网站:购买帆布运动鞋和经典皮鞋
2016/11/12 全球购物
英国奢侈品网站:MatchesFashion
2016/12/16 全球购物
美国高品质个性化珠宝销售网站:Jewlr
2018/05/03 全球购物
Lentiamo比利时:便宜的隐形眼镜
2020/02/14 全球购物
生物化学研究助理员求职信
2013/10/09 职场文书
土木工程毕业生推荐信
2013/10/28 职场文书
活动策划邀请函
2014/02/06 职场文书
“四风”问题的主要表现和危害思想汇报
2014/09/19 职场文书
汽车转让协议书
2015/01/29 职场文书
动画「进击的巨人」第86话播出感谢绘公开
2022/03/21 日漫