网站

thinkphp5 Validate验证功能 及allowField说明 数组验证方法

分类 :thinkphp5     2019-04-17 人气:0 0条评论

TP为我们提供的验证功能非常强大好用

目前我们创建了一个名叫Tp的模型,方法页面中我们写一个rli方法用于填写表单页,rliadd方法用于接收我们提交的数据
Tp模型只是建立,未放内容,便不发出来了

方法文件

rli方法

return view('index/create');
只是引入模板文件,引入后的样子
thinkphp5 Validate验证功能 及allowField说明 数组验证方法

rliadd方法

  • 自动收集表单数据 input('post.')
  • 自动过滤post数组中的非数据表字段数据 allowField(true),当是allowField(false)时,如果提交过来的表单含有数据表中没有的字段,那便会提示提交失败
  • 自动校验非法字段 validate(true)
  • 自动生成insert语句 执行入库 save(input('post.'))
public function rliadd()
	{		
		$tp = new Tp;
		if($tp->allowField(true)->validate(true)->save(input('post.')))
		{
			return '用户[' .$tp->name. ':' .$tp->id. ']新增成功';
		}else
		{
			return $tp->getError();
		}
	}

Validate验证

上面是准备工作,接下来我们开始验证部分
目前我们的文件放在application\admin目录中,目录结构
thinkphp5 Validate验证功能 及allowField说明 数组验证方法

validate文件夹中新建Tp.php文件,没有这个文件夹的请自建Tp.php文件是与前面的Tp模型相同的
$rule是验证规则
$message是用户提交时不符合规则的返回信息
<?php
namespace app\admin\validate;
use think\Validate;

class Tp extends Validate
{
	#验证规则
	protected $rule = [
		'name' => 'require|min:2',
		'email' => 'email',
		'tel' => 'require|min:8,11'
	];
	
	protected $message = [
		'name.require' => '用户名不能为空',
		'name.min' => '用户名不能少于两位',
		'email' => '邮箱格式错误',
		'tel.require' => '电话不能为空'
		'tel.min' => '电话位数为8到11位之间'
	];
}
这时候使用时已经启用验证功能了。

上传一张图,看看上面的流程中TP为我们自动做了哪些事情
thinkphp5 Validate验证功能 及allowField说明 数组验证方法

添加自定义验证功能

验证方法可以传入的参数共有5个(后面三个根据情况选用),依次为:

自定义验证方法名称(验证数据,验证规则,全部数据(数组),字段名,字段描述)

我们对其它的未变,只对邮箱进行自定义验证,此次邮箱采用了两种验证,也就是email|ckMail:xiuyuanxi.com这段
class Tp extends Validate
{
	#验证规则
	protected $rule = [
		'email' => 'email|ckMail:xiuyuanxi.com'
	];
	
	protected $message = [
		'email' => '邮箱格式错误'
	];
	
	#使用自定义函数进行验证
	protected function ckMail($value,$rule)
	{
		$result = strstr($value,$rule);
		if($result)
			return true;
		else
			return "邮箱必须包含 $rule";
	}
}

控制器验证方法

依然是用上方TP验证器内的验证内容,只是我们方法中写的接收代码,验证代码的方式变了
public function rliadd()
	{	
		
		#控制器验证
		$data = input('post.');
		#数据验证
		#$this->validate($data,'Tp')  $data 是获取的数据,Tp是验证器名
		$result = $this->validate($data,'Tp');
				
		if(true !== $result) #判断是不是true
		{
			return $result;
		}
		
		#数据保存部分
		$tp = new Tp;
		$tp->allowField(true)->save($data);
		return '用户[' .$tp->name. '---' .$tp->id. ']新增成功';

静态验证方式

其实TP提供了很多静态验证方法,只是说明文档中并未全部指出
下面只列出一些验证的名称,建议直接看原文件有详细使用有哪些参数(其实不难),文件位置thinkphp\library\think下的Validate.php
Validate::dateFormat  #用于日期格式验证
Validate::in #验证是否在某个范围
Validate::gt #验证是否大于某个值
Validate::regex #正则验证

Validate::is

此方法中含有很多规则,写在这:
require #验证必须
accepted #验证接受
date #验证是否是一个有效日期
alpha #验证只允许字母
alphaNum #验证只允许字母和数字
alphaDash #验证只允许字母、数字和下划线 破折号
chs #验证只允许汉字
chsAlpha #验证只允许汉字、字母
chsAlphaNum #验证只允许汉字、字母和数字
chsDash #验证只允许汉字、字母、数字和下划线_及破折号-
activeUrl #验证是否为有效的网址
ip #验证是否为IP地址
url #验证是否为一个URL地址
float #验证是否为float
number #验证 这个代码中未标注,应该是是否为数字
integer #验证是否为整型
email #验证是否为邮箱地址
boolean #验证是否为布尔值
array #验证是否为数组
file #验证 这个代码中未标注 可能是是否为文件
image #验证 这个也未标注
token #验证 这个也未标注
还有一些其它的,如二维码一类的~

上面将文件中的部分标记标注出来,接下来回到运用静态规则验证
使用前加上:use think\Validate;,否则会出报错

public function rliadd()
	{	
		#单独给某个字段验证
		$data = input('post.');
		#验证姓名是否是汉字
		#Validate::is 是Validate的一个静态类is,$data['name']是获取的数据,chs是内置的验证规则
		$check = Validate::is($data['name'],'chs');
		
		if(false === $check)
		{
			return "只允许汉字";
		}
		
		$tp = new Tp;
		$tp->allowField(true)->save($data);
		return '用户[' .$tp->name. '---' .$tp->id. ']新增成功';

当前页面中写验证规则

除了在验证器中写验证规则外,还可以直接在方法中写验验规则
下方的$data是数据,$validate是验证规则,$validate->check($data);是进行验证
    public function getBanner($id)
    {
        $data = [
            'name' => 'vendor',
            'email' => 'vendor@qq.com',
        ];

        $validate = new Validate([
            'name' => 'require|max:10',
            'email' => 'email'
        ]);

        $result = $validate->check($data);
    }

自定义验证 输入的是否为正整数

protected $rule = [
        'id' => 'require|isPositiveInteger'
    ];

    protected  function  isPositiveInteger($value,$rule='',$data='',$field='')
    {
        #$value + 0 是因为原先$value是一个字符串,运用加0的方式转换成数值变量
        if(is_numeric($value) && is_int($value + 0) && ($value + 0)>0){
            return '验证成功';
        }else{
            return $field . '必须是正整数';
        }

一个统一验证的实例

前面的控制器中,要使用验证功能,基本包含获取传入值,将传入值放入验证器,对返回值进行判断后输出,我们将这些进行封装后处理

所需要文件

  • Banner.php  控制器文件
  • BaseValidate.php  总验证器文件
  • IDMustBePostiveInt.php  验证规则文件

Banner.php内容

记得要引入IDMustBePostiveInt类,否则无法new这个类
  • use app\api\validate\IDMustBePostiveInt;
<?php
namespace app\api\controller\v1;
use think\Controller;
use think\Validate;
use app\api\validate\IDMustBePostiveInt;

class Banner extends Controller
{
    /**
     * 获取指定id的banner信息
     * @url /banner/:id
     * @http GET
     * @id banner的id号
     */
    public function getBanner()
    {
        (new IDMustBePostiveInt())->goCheck();
    }
}

BaseValidate.php文件

里面的goCheck方法便是我们的公共方法,后期所有页面中直接使用该方法,上面的Banner.php中,我们便是直接调用此方法
<?php
namespace app\api\validate;
use think\Exception;
use think\Validate;

class BaseValidate extends Validate
{
    public function goCheck()
    {
        /**
         * 对所有传入的参数先到此进行验证
         * 获取http传入的参数
         * 对参数进行校验
         */
        $request = input('param.');

        $result = $this->check($request);
        if(!$result){
            $error = $this->error;  #错误信息
            exception($error); #抛出异常,并将错误信息放入
        }else{
            return true;
        }
    }
}

IDMustBePostiveInt.php内容

  • 我们在文件中不再是继承Validate,而是继承BaseValidate,所以要写成
class BaseValidate extends Validate
  • 同时,也不再需要引入use think\Validate;这条
<?php
namespace app\api\validate;

class IDMustBePostiveInt extends BaseValidate
{
    protected $rule = [
        'id' => 'require|isPositiveInteger'
    ];

    protected  function  isPositiveInteger($value,$rule='',$data='',$field='')
    {
        #$value + 0 是因为原先$value是一个字符串,运用加0的方式转换成数值变量
        if(is_numeric($value) && is_int($value + 0) && ($value + 0)>0){
            return '验证成功';
        }else{
            return $field . '必须是正整数';
        }
    }
}

批量验证batch

如上面的 
protected $rule = [
        'id' => 'require|isPositiveInteger',
    ];

调用验证时上面用的是$result = $this->check($request);
  • 这时输入http://127.0.0.1/banner/1.0,输出的是
{"msg":{"id":"id必须是正整数"},"error_code":10000,"request_url":""}

但验证规则若变成
protected $rule = [
        'id' => 'require|isPositiveInteger',
        'num' => 'in:1,2,3'
    ];
因为有多个参数,所以我们要用$result = $this->batch()->check($params);

我们输入http://127.0.0.1/banner/1.0?num=5
{"msg":{"id":"id必须是正整数","num":"num必须在 1,2,3 范围内"},"error_code":10000,"request_url":""}

数组验证

protected $products = [
	['protected_id'=>1, 'count'=>3],
	['protected_id'=>2, 'count'=>4],
	['protected_id'=>3, 'count'=>1],
	['protected_id'=>4, 'count'=>5],	
	];
针对于$products是数组,并要对其进行验证,可以使用下面的双验证方式,解析内容见下方
protected $rule = [
      'products' => 'checkProducts'
    ];

   
    protected $singleRule = [
        'protected_id' => 'require|isPostitiveInteger' ,
        'count' => 'require|isPOsitiveInteger'
    ];

    protected function checkProducts($values)
    {
        if(!is_array($values)){
            throw new BaseException(['code' => 404,'msg' => '参数不正确','errorCode' => 60000]);
        }

        if(empty($values)){
            throw new BaseException(['code' => 404,'msg' => '商品列表不能为空','errorCode' => 60000]);
        }

        foreach ($values as $value) {
            $this->checkProduct($value);
        }
        return true;
    }

    protected function checkProduct($value)
    {
        $validate = new BaseValidate($this->singleRule);
        $result = $validate->check($value);
        if(!$result){
            throw new BaseException(['msg'=>'商品列表参数错误']);
        }
上面语法的解析

protected $rule :$products进行验证,验证的方式放在了checkProducts中,主要是验证是不是一个数组,是数组则调用checkProduct

protected $singleRule:是对数组内容的一系列验证,但除了protected $rule外,其它的验证规则TP默认不会自动执行,所以写了checkProduct方法,当checkProducts断定为数组后,使用checkProduct调用该方法,里面的BaseValidate可以忽略,这只是个判断是否有内容的功能


评论

大侠名号:   验证暗号: 点击我更换图片

继续阅读