验证器定义
验证器定义
- 验证器的使用,我们必须先定义它,系统提供了一条命令直接生成想要的类;
php think make:validate User
- 这条命令会自动在应用目录下生成一个
validate
文件夹,并生成User.php
类;
class User extends Validate
- 自动生成了两个属性:
$rule
表示定义规则,$message
表示错误提示信息;
protected $rule = [
'name' => 'require|max:20', //不得为空,不得大于 20 位
'price' => 'number|between:1,100', //必须是数值,1-100 之间
'email' => 'email' //邮箱格式要正确
];
protected $message = [
'name.require' => '姓名不得为空',
'name.max' => '姓名不得大于 20 位',
'price.number' => '价格必须是数字',
'price.between' => '价格必须 1-100 之间',
'email' => '邮箱的格式错误'
];
- 如果不设置
$message
定义的话,将提示默认的错误信息; - 验证器定义好了之后,我们需要进行调用测试;
try {
validate(User::class)->check([
'name' => '蜡笔小新',
'price' => 90,
'email' => 'xiaoxin@163.com'
]);
} catch (ValidateException $e) {
dump($e->getError());
}
- 默认情况下,出现一个错误就会停止后面字段的验证,我们也可以设置批量验证;
try {
validate(User::class)->batch(true)->check([
'name' => '蜡笔小新',
'price' => 90,
'email' => 'xiaoxin@163.com'
]);
} catch (ValidateException $e) {
dump($e->getError());
}
- 系统提供了常用的规则让开发者直接使用,也可以自行定义独有的特殊规则;
protected $rule = [
'name' => 'require|max:20|checkName:李炎恢',
];
//自定义规则,名称中不得是“李炎恢”
protected function checkName($value, $rule)
{
return $rule != $value ? true : '名称存在非法称谓';
}
- 对于自定义规则中,一共可以有五个参数,我们分别了解一下;
protected function checkName($value, $rule, $data, $field, $title)
{
dump($data); //所有数据信息
dump($field); //当前字段名
dump($title); //字段描述,没有就是字段名
}
- 如何设置字段描述,只要在字段名用
|
后设置即可:'name|用户名' => 'require|max:20|checkName:李炎恢',
验证规则和错误信息
验证规则
- 在上一节验证器定义的时候,我们采用的字符串模式,也支持数组模式;
protected $rule = [
'name' => [
'require',
'max' => 10,
'checkName' => '李炎恢'
],
'price' => [
'number',
'between' => '1,100'
],
'email' => 'email'
];
- 数组模式在验证规则很多很乱的情况下,更容易管理,可读性更高;
- 如果你想使用独立验证,就是手动调用验证类,而不是调用
User.php
验证类; - 这种调用方式,一般来说,就是独立、唯一,并不共享的调用方式;
$validate = Validate::rule([
'name' => 'require|max:20',
'price' => 'number|between:1,100',
'email' => 'email'
]);
$result = $validate->check([
'name' => '1997sty',
'price' => 90,
'email' => 'xiaoxin163.com'
]);
if (!$result) {
dump($validate->getError());
}
- 独立验证默认也是返回一条错误信息,如果要批量返回所有错误使用
batch()
;
$validate = Validate::rule([
'name' => 'require|max:20',
'price' => 'number|between:1,100',
'email' => 'email'
]);
$result = $validate->batch(true)->check([
'name' => '1997sty',
'price' => 90,
'email' => 'xiaoxin163.com'
]);
if (!$result) {
dump($validate->getError());
}
- 独立验证支持对象化的定义方式,但不支持在属性方式的定义;
$validate = Validate::rule([
'name' => ValidateRule::isRequire()->max(20),
'price' => ValidateRule::isNumber()->between([1, 100]),
'email' => ValidateRule::isEmail()
]);
- 独立验支持闭包的自定义方式,但这种方式会不支持字段的多规则;
$validate = Validate::rule([
'name' => function ($value) {
return $value != '' ? true : '姓名不得为空';
},
'price'=> function ($value) {
return $value > 0 ? true : '价格不得小于零';
}
]);
错误信息
- 独立验证的自定义错误提示,可以在方法的第二参数,参数一是规则;
ValidateRule::isEmail(null, '邮箱格式不正确!');
ValidateRule::isNumber()->between([1, 100], '价格范围 1-100 之间');
- 也可以独立使用 message()方法,来设置相关错误信息;
$validate->message([
// 'name.require' => '姓名不得为空',
'name.require' => ['code'=>1001, 'msg'=>'姓名不得为空'],
'name.max' => '姓名不可以超过 20 个子'
]);
验证场景和路由验证
验证场景
- 验证场景设置,即特定的场景下是否进行验证,独立验证不存在场景验证;
- 举一个简单的例子,新增数据需要验证邮箱,而修改更新时不验证邮箱;
- 可以在验证类
User.php
中,设置一个$scene
属性,用来限定场景验证;
protected $scene = [
'insert' => ['name', 'price', 'email'],
'edit' => ['name', 'price'],
];
- 上述中,
insert
新增需要验证三个字段,而edit
更新则只要验证两个字段; - 在控制器端,验证时,根据不同的验证手段,绑定相关场景进行验证即可;
$validate->scene('edit')->check($data);
- 在验证类端,可以设置一个公共方法对场景的细节进行定义;
public function sceneEdit()
{
$edit = $this->only(['name', 'price']) //仅对两个字段验证
->remove('name', 'max') //移出掉最大字段的限制
->append('price', 'require'); //增加一个不能为空的限制
return $edit;
}
- 注意:请不要对一个字段进行两个或以上的移出和添加,会被覆盖;
remove('name', 'xxx|yyy|zzz')或 remove('name', ['xxx', 'yyy', 'zzz']);
而不是
remove('name', 'xxx')->remove('name', 'yyy')->remove('name', 'zzz');
路由验证
- 路由验证,即在路由的参数来调用验证类进行验证,和字段验证一模一样;
protected $rule = [
'id' => 'number|between:1,10'
];
protected $message = [
'id.between' => 'id 只能是 1-10 之间',
'id.number' => 'id 必须是数字'
];
Route::rule('vr/:id','Verify/route')->validate(\app\validate\User::class, 'route');
// 特别注意:这里有一个 BUG,v6.0.2 修复了,使用 composer update。
- 如果不使用验证器类,也可以使用独立的验证方式,也可以使用对象化;
Route::rule('vr/:id','Verify/route')->validate([
'id' => 'number|between:1,10',
'email' => \think\validate\ValidateRule::isEmail()
], null, [
'id.between' => 'id 限定在 1-10 之间',
'email' => '邮箱格式错误'
], true);
验证内置规则
内置规则
- 内置的规则内容较多,并且严格区分大小写,这里按照类别一一列出;
- 静态方法支持两种形式,比如
::number()
或者isNumber()
均可; - 而
require
是PHP保留字,那么就必须用isRequire()
或must()
; - 格式验证类:
'field' => 'require', //不得为空::isRequire 或::must
'field' => 'number', //是否是纯数字,非负数非小数点
'field' => 'integer', //是否是整数
'field' => 'float', //是否是浮点数
'field' => 'boolean', //是否是布尔值,或者 bool
'field' => 'email', //是否是 email
'field' => 'array', //是否是数组
'field' => 'accepted', //是否是“yes”“no”“1”这三个值
'field' => 'date', //是否是有效日期
'field' => 'alpha', //是否是纯字母
'field' => 'alphaNum', //是否是字母和数字
'field' => 'alphaDash', //是否是字母和数字以及_-(下划线和破折号)
'field' => 'chs', //是否是纯汉字
'field' => 'chsAlpha', //是否是汉字字母
'field' => 'chsAlphaNum', //是否是汉字字母数字
'field' => 'chsDash', //是否是汉字字母数字以及_-(下划线和破折号)
'field' => 'cntrl', //是否是控制字符(换行、缩进、空格)
'field' => 'graph', //是否是可打印字符(空格除外)
'field' => 'print', //是否是可打印字符(包含空格)
'field' => 'lower', //是否是小写字符
'field' => 'upper', //是否是大写字符
'field' => 'space', //是否是空白字符
'field' => 'xdigit', //是否是十六进制
'field' => 'activeUrl', //是否是有效域名或 IP 地址
'field' => 'url', //是否是有效 URL 地址
'field' => 'ip', //是否是有效 IP(支持 ipv4,ipv6)
'field' => 'dateFormat:Y-m-d', //是否是指定日期格式
'field' => 'mobile', //是否是有效手机
'field' => 'idCard', //是否是有效身份证
'field' => 'macAddr', //是否是有效 MAC 地址
'field' => 'zip', //是否是有效邮编
- 长度和区间验证类:
'field' => 'in:1,2,3', //是否是有某个值
'field' => 'notIn:1,2,3', //是否是没有某个值
'field' => 'between:1,100', //是否是在区间中
'field' => 'notBetween:1,100', //是否是不在区间中
'field' => 'length:2,20', //是否字符长度在范围中
'field' => 'length:4', //是否字符长度匹配
'field' => 'max:20', //是否字符最大长度
'field' => 'min:5', //是否字符最小长度
//length、max、min 也可以判断数组长度和 File 文件大小
'field' => 'after:2020-1-1', //是否在指定日期之后
'field' => 'before:2020-1-1', //是否在指定日期之前
//是否在当前操作是否在某个有效期内
'field' => 'expire:2019-1-1,2020-1-1',
//验证当前请求的 IP 是否在某个范围之间,
'field' => 'allowIp:221.221.78.1, 192.168.0.1',
//验证当前请求的 IP 是否被禁用
'field' => 'denyIp:221.221.78.1, 127.0.0.1',
- 字段比较类:
'field' => 'confirm:password', //是否和另一个字段匹配
'field' => 'differnet:password',//是否和另一个字段不匹配
'field' => 'eq:100', //是否等于某个值,=、same 均可
'field' => 'gt:100', //是否大于某个值,支持>
'field' => 'egt:100', //是否大于等于某个值,支持>=
'field' => 'lt:100', //是否小于某个值,支持<
'field' => 'elt:100', //是否小于等于某个值,支持<=
//比较方式也支持字段比较,比如:'field'=>'lt:price' 7. 其它验证类:
'field' => '\d{6}', //正则表达式验证
'field' => 'regex:\d{6}', //正则表达式验证
'field' => 'file', //判断是否是上传文件
'field' => 'image:150,150,gif', //判断图片(参数可选)
'field' => 'fileExt:jpg,txt', //判断文件允许的后缀
'field' => 'fileMime:text/html',//判断文件允许的文件类型
'field' => 'fileSize:2048', //判断文件允许的字节大小
'field' => 'unique:user', //验证 field 字段的值是否在 user 表
'field' => 'requireWith:account',//当 account 有值时,requireWidth 必须
'email' => 'requireWithout:name',
'name' => 'requireWithout:email', //name 和 email 必须有一个有值
单个验证和注解验证
单个验证
- 静态调用,即使用
facade
模式进行调用验证,非常适合单个数据的验证; - 引入
facade
中的Validate
时,和其它Validate
会冲突,要特别注意;
//验证邮箱是否合法
dump(Validate::isEmail('xiaoxin@163.com'));
//验证是否为空
dump(Validate::isRequre(''));
//验证是否为数值
dump(Validate::isNumber(10));
- 静态调用返回的结果是
false
和true
,方便你进行条件判断; - 静态调用,也是支持多规则验证的,使用
checkRule()
方法实现;
//验证数值合法性
dump(Validate::checkRule(10, 'number|between:1,10'));
checkRule()
不支持错误信息,需要自己实现,但支持对象化规则定义;
dump(Validate::checkRule(10, ValidateRule::isNumber()->between('1,10')));
注解验证
- 可以结合之前课程中注解路由的传参,使用验证方式,对其进行验证;
use think\annotation\Route;
use think\annotation\route\Validate;
/**
* @param $id
* @return string
* @route("vr/:id")
* @Validate(User::class)
*/
最后一次更新于2020-08-04 17:26
0 条评论