请求参数校验

1.前言

本小节主要介绍如何使用 ThinkPHP 提供的 Validate 验证器,它可以在控制器接收参数之前验证参数,若参数不合符业务要求,就会返回相应的错误提示,在实际工作中,数据校验的是一项必不可少的工作,数据的严格校验可能减少很多不必要的代码执行,这从某种层面来说减少了服务器压力,从安全角度来说,数据校验能避免某些不必要的 BUG,比如对手机号码的校验,能有效地阻止后期发送短信失败导致的 BUG能有效地防止 XSSSQL注入等攻击。

2.新建验证器类

这里以之前添加学生接口为例,该接口入参需要 学生姓名(name)年龄(age)身份证号(id_number),首先新建一个 app\Validate 目录,然后在该目录下新建一个 StudentValidate 类,代码如下:

<?php

namespace app\Validate;


use think\Validate;

class StudentValidate extends Validate
{

}

如下图所示:
图片描述

3.设置字段验证规则

字段的验证规则可以在 protected $rule 中设置如下规则:

    /**
     * 设置字段验证规则
     * @var string[]
     */
    protected $rule = [
        'name' => 'require|max:5',
        'age' => 'number|between:1,120',
        'id_number' => 'require|in:18',
    ];

如下图所示:
图片描述

4.设置不满足规则的提示语

若想要设置不满足验证规则字段的错误提示语,可在 protected $message 中设置如下内容:

    /**
     * 设置不满足字段要求的提示语
     * @var string[]
     */
    protected $message = [
        'name.require' => '学生姓名不能为空',
        'name.max' => '学生姓名长度不能超过5',
        'age.number' => '学生年龄必须是数字',
        'age.between' => '学生年龄值必须是1-120之间',
        'id_number.require' => '学生身份证号不能为空',
        'id_number.in' => '学生身份证号必须是18位'
    ];

如下图所示:
图片描述

5.设置验证场景

若想要在不同场景下验证不同的字段,可在 protected $scene 总设置如下内容:

    /**
     * 设置验证场景
     * @var string[][]
     */
    protected $scene = [
        'add-student' => ['name', 'age', 'id_number'],
        'edit-student' => ['name', 'age']
    ];

如下图所示:
图片描述

6.在控制器中调用验证器

可以在学生添加接口的控制器中增加如下内容:

validate(StudentValidate::class)->scene('add-student')->check($this->request->param());

如下图所示:
图片描述

Tips: 其中 validate() 是一个框架提供的一个辅助函数,scene('add-student') 表示验证场景是 add-student$this->request->param() 表示接口传入的参数。

7.请求接口验证

postman 中请求上述接口,如下图是缺少学生 name 字段提示的错误:
图片描述

学生 name 字段超过长度提示如下:
图片描述

8.内置验证规则表

下面列出 ThinkPHP 提供的内置验证规则:

验证规则名 含义
require 验证字段为必须
number 验证字段是否为数字类型
integer 验证字段是否为整数
float 验证字段是否为浮点型
boolean 或 bool 验证字段是否为布尔值
email 验证字段是否符合邮箱格式
array 验证字段是否为数组
date 验证字段是否为有效的日期
alpha 验证字段是否为纯字母
alphaNum 验证字段是否为字母+数字混合
alphaDash 验证字段是否为字母+数字+_+-混合
chs 验证字段是否为 汉字
chsAlpha 验证字段是否为 汉字+字母混合
chsAlphaNum 验证字段是否为 汉字+字母+数字混合
chsDash 验证字段是否为 汉字+字母+数字+_+-混合
cntrl 验证字段是否控制字符(换行、缩进、空格)
graph 验证字段是否为可打印字符(空格除外)
print 验证字段是否为可打印字符(包括空格)
lower 验证字段是否为小写字母
upper 验证字段是否为大写字母
space 验证字段是否为空白字符(包括缩进,垂直制表符,换行符,回车和换页字符)
xdigit 验证字段是否为十六进制字符串
url 验证字段是否为有效的URL地址
ip 验证字段是否为有效的IP地址,支持验证ipv4和ipv6格式的IP地址
dateFormat:format 验证字段是否为指定格式的日期,如 dateFormat:y-m-d 表示年月日
mobile 验证字段是否为有效的手机格式
idCard 验证字段是否为有效的身份证格式
macAddr 验证字段是否为有效的MAC地址
zip 验证字段是否为有效的邮政编码
in 验证字段是否为是否在某个范围,如 in:1,2,3 表示取值在 1,2,3
notIn 验证字段是否为不在某个范围
between 验证字段是否为在某个区间,如 between:1,10 表示 1-10 之间
notBetween 验证字段是否为不在某个范围
length:num1,num2 验证字段是否为长度是否在某个范围,如 length:4,25 长度在 4-25,length:4 表示指定长度,如果验证的数据是数组,则判断数组的长度。如果验证的数据是File对象,则判断文件的大小。
max:number 验证字段的 最大长度,如 max:10 表示最大长度 10,注意不包含字段不存在的情况,如果验证的数据是数组,则判断数组的长度。如果验证的数据是File对象,则判断文件的大小。
min:number 验证字段的 最小长度,如min:5 表示最小长度 5,注意不包含字段不存在的情况,如果验证的数据是数组,则判断数组的长度。如果验证的数据是File对象,则判断文件的大小。
after:日期 验证字段是否为在某个日期之后,如 after:2020-11-18 表示 2020-11-18 之后
before:日期 验证字段是否为在某个日期之前,如 after:2020-11-18 表示 2020-11-18 之前
expire:开始时间,结束时间 验证当前操作(注意不是某个值)是否在某个有效日期之内,如expire:2020-1-21,2020-5-1表示 2020-01-212020-05-01 之间
allowIp:allow1,allow2,… 验证当前请求的IP是否允许访问,如 'allowIp:114.45.4.55' 表示ip为 114.45.4.55
denyIp:allow1,allow2,… 验证当前请求的IP是否禁止访问,如 denyIp:114.45.4.55
confirm 验证字段是否为和另外一个字段值一致,如 confirm:new_value 表示当前判断字段值是否和 new_value 字段值一致
eq 或者 = 或者 same 验证字段是否为等于某个值,如eq:100 表示等于 100=:10 表示等于 10,same:20 表示等于 20
egt 或者 >= 验证字段是否为大于等于某个值,如 egt:30表示大于等于30>=50 表示大于等于50
gt 或者 > 验证字段是否为大于某个值,同上
elt 或者 <= 验证字段是否为小于等于某个值,同上
lt 或者 < 验证字段是否为小于某个值
file 验证字段是否为一个上传文件
image:width,height,type 验证字段是否为一个图像文件,其中 width,height和type都是可选,width和height必须同时定义
fileExt:允许的文件后缀 验证字段是否为上传文件后缀
fileMime:允许的文件类型 验证字段是否为上传文件类型
fileSize:允许的文件字节大小 验证字段是否为上传文件大小
token:表单令牌名称 表单令牌验证
unique:table,field,except,pk 验证当前请求的字段值是否为唯一的
requireIf:field,value 验证某个字段的值等于某个值的时候必须
requireWith:field 验证某个字段有值的时候必须
requireWithout:field 验证某个字段没有值的时候必须
requireCallback:callable 验证当某个callable为真的时候字段必须

9.小结

本小节主要介绍如何使用 ThinkPHP 提供的 Validate 验证器,它可以帮助快速有效地验证请求数据的有效性和正确性,另外还列举了不同场景下内置的字段验证规则,需要注意的是上面学生身份证号码的验证可以使用 isCard

Tips: 代码仓库:https://gitee.com/love-for-poetry/tp6