## 数据验证 数据验证也是系统改动比较大的一个地方。 模型中,可以定义`$validate`属性设定数据验证规则,当你需要写入数据时(使用模型非db写入),系统会自动验证。这里并不是真的使用tp自带的模型数据验证(新版tp已经取消了模型验证),同样是使用实例化Validate对象来进行数据验证。 先总览下`$validate`格式: ~~~ protected $validate = [ //字段只有一个规则 '字段1' => [ 'rule' = > '验证规则', 'message' => '错误信息提示', 'on' => 'add' ], //字段有一个或多个规则 '字段2' => [ [ 'rule' = > '验证规则', 'message' => '错误信息提示', 'on' => 'edit' ], [ 'rule' = > '验证规则' ] ] ]; ~~~ 以字段为键 => 规则数组 字段键下可以是一维数组(只有一个规则),也可以是二维数组(定义一个或多个规则)。 每个规则下可以有4个关键词:rule、message、on ### message: 用于定义错误提示信息,如果没有使用TP框架默认值处理 * * * * * ### on: 用于定义验证场景,系统默认有的验证场景有2个: add:添加场景 edit:修改场景 ~~~ [ 'on' => 'add' //只会在 新增 时验证该规则 ] [ 'on' => 'edit' //只会在 更新 时验证该规则 ] ~~~ 如果没有定义on关键词,表示 新增 和 更新 都会验证该规则。 * * * * * ### rule: rule关键词,每个规则都**必须**含有,用于定义当前验证规则。 我们定义的数据验证数组,最后系统还是自动会处理成TP能识别的那种格式,所以rule支持TP本身所有的验证规则。 [TP内置规则传送门](https://www.kancloud.cn/manual/thinkphp6_0/1037629) #### 格式验证类 require:验证某个字段必须,例如: ~~~ [ 'rule' => 'require' ] ~~~ number 或者 integer :验证某个字段的值是否为数字(采用filter_var验证),例如: ~~~ [ 'rule' => 'number' ] ~~~ float:验证某个字段的值是否为浮点数字(采用filter_var验证),例如: ~~~ [ 'rule' => 'float' ] ~~~ boolean:验证某个字段的值是否为布尔值(采用filter_var验证),例如: ~~~ [ 'rule' => 'boolean' ] ~~~ email:验证某个字段的值是否为email地址(采用filter_var验证),例如: ~~~ [ 'rule' => 'email' ] ~~~ array:验证某个字段的值是否为数组,例如: ~~~ [ 'rule' => 'array' ] ~~~ accepted:验证某个字段是否为为 yes, on, 或是 1。这在确认"服务条款"是否同意时很有用,例如: ~~~ [ 'rule' => 'accepted' ] ~~~ date:验证值是否为有效的日期,例如: ~~~ [ 'rule' => 'date' ] ~~~ alpha:验证某个字段的值是否为字母,例如: ~~~ [ 'rule' => 'alpha' ] ~~~ alphaNum:验证某个字段的值是否为字母和数字,例如: ~~~ [ 'rule' => 'alphaNum' ] ~~~ alphaDash:验证某个字段的值是否为字母和数字,下划线_及破折号-,例如: ~~~ [ 'rule' => 'alphaDash' ] ~~~ chs:验证某个字段的值只能是汉字,例如: ~~~ [ 'rule' => 'chs' ] ~~~ chsAlpha:验证某个字段的值只能是汉字、字母,例如: ~~~ [ 'rule' => 'chsAlpha' ] ~~~ chsAlphaNum:验证某个字段的值只能是汉字、字母和数字,例如: ~~~ [ 'rule' => 'chsAlphaNum' ] ~~~ chsDash:验证某个字段的值只能是汉字、字母、数字和下划线_及破折号-,例如: ~~~ [ 'rule' => 'chsDash' ] ~~~ activeUrl:验证某个字段的值是否为有效的域名或者IP,例如: ~~~ [ 'rule' => 'activeUrl' ] ~~~ url:验证某个字段的值是否为有效的URL地址(采用filter_var验证),例如: ~~~ [ 'rule' => 'url' ] ~~~ ip:验证某个字段的值是否为有效的IP地址(采用filter_var验证),例如: ~~~ [ 'rule' => 'ip' ] ~~~ dateFormat:验证某个字段的值是否为指定格式的日期,例如: ~~~ [ 'rule' => ['dateFormat', 'y-m-d'] ] [ 'rule' => 'dateFormat:y-m-d' ] ~~~ #### 长度和区间验证类 in:验证某个字段的值是否在某个范围,例如: ~~~ [ 'rule'=>['in', '1,2,3'] ] [ 'rule' => 'in:1,2,3' ] [ 'rule' => ['in', 1, 2, 3] ] ~~~ notIn:验证某个字段的值是否在某个范围,例如: ~~~ [ 'rule'=>['notIn', '1,2,3'] ] [ 'rule' => 'notIn:1,2,3' ] [ 'rule' => ['notIn', 1, 2, 3] ] ~~~ between:验证某个字段的值是否在某个区间,例如: ~~~ [ 'rule'=>['between', '1,10'] ] [ 'rule' => 'between:1,10' ] [ 'rule' => ['between', 1, 10] ] ~~~ notBetween:验证某个字段的值不在某个范围,例如: ~~~ [ 'rule'=>['notBetween', '1,10'] ] [ 'rule' => 'notBetween:1,10' ] [ 'rule' => ['notBetween', 1, 10] ] ~~~ length:验证某个字段的值的长度是否在某个范围,例如: ~~~ [ 'rule'=>['length', '4,25'] ] [ 'rule' => 'length:4,25' ] [ 'rule' => ['length', 4, 25] ] ~~~ max:验证某个字段的值的最大长度,例如: ~~~ [ 'rule'=>['max', '25'] ] [ 'rule' => 'max:25' ] ~~~ min:验证某个字段的值的最小长度,例如: ~~~ [ 'rule'=>['min', '5'] ] [ 'rule' => 'min:5' ] ~~~ after:验证某个字段的值是否在某个日期之后,例如: ~~~ [ 'rule'=>['after', '2016-3-18'] ] [ 'rule' => 'after:2016-3-18' ] ~~~ before:验证某个字段的值是否在某个日期之前,例如: ~~~ [ 'rule'=>['before', '2016-3-18'] ] [ 'rule' => 'before:2016-3-18' ] ~~~ expire:验证当前操作(注意不是某个值)是否在某个有效日期之内,例如: ~~~ [ 'rule'=>['expire', '2016-2-1', '2016-10-1'] ] [ 'rule' =>'expire:2016-2-1,2016-10-01' ] [ 'rule' =>['expire', '2016-2-1, 2016-10-1'] ] ~~~ allowIp:验证当前请求的IP是否在某个范围,例如: ~~~ [ 'rule'=>['allowIp', '114.45.4.55', '114.45.4.56'] ] [ 'rule' =>'allowIp:114.45.4.55,114.45.4.56' ] [ 'rule' =>['allowIp', '114.45.4.55, 114.45.4.56'] ] ~~~ denyIp:验证当前请求的IP是否禁止访问,例如: ~~~ [ 'rule'=>['denyIp', '114.45.4.55', '114.45.4.56'] ] [ 'rule' =>'denyIp:114.45.4.55,114.45.4.56' ] [ 'rule' =>['denyIp', '114.45.4.55, 114.45.4.56'] ] ~~~ eq :验证是否等于某个值,例如: ~~~ [ 'rule'=>['eq', 100] ] [ 'rule' =>'=:100' ] //手册上可以= 和same,测试报错 ~~~ egt :验证是否大于等于某个值,例如: ~~~ [ 'rule'=>['egt', 100] ] [ 'rule' =>'egt:100' ] ~~~ gt :验证是否大于某个值,例如: ~~~ [ 'rule'=>['gt', 100] ] [ 'rule' =>'gt:100' ] ~~~ elt :验证是否小于等于某个值,例如: ~~~ [ 'rule'=>['elt', 100] ] [ 'rule' =>'elt:100' ] ~~~ lt :验证是否小于某个值,例如: ~~~ [ 'rule'=>['lt', 100] ] [ 'rule' =>'lt:100' ] ~~~ lt :验证是否小于某个值,例如: ~~~ [ 'rule'=>['lt', 100] ] [ 'rule' =>'lt:100' ] ~~~ #### filter验证 支持使用filter_var进行验证,例如: ~~~ 'rule' =>'filter:validate_ip' ~~~ #### 正则验证 支持使用正则验证,例如: ~~~ 'rule' =>['regex', '/^(yes|on|1)$/i'] ~~~ #### 其他 unique:table,field,except,pk:验证当前请求的字段值是否为唯一的,例如: ~~~ 'rule' => ['unique', 'user'] ~~~ requireIf:field,value:验证某个字段的值等于某个值的时候必须,例如: ~~~ 'rule' => 'requireIf:account,1' ~~~ requireWith:field:验证某个字段有值的时候必须,例如: ~~~ 'rule' => 'requireWith:account' ~~~ #### 自定义验证规则 call : 通过自定义模型方法回调验证 ~~~ 'rule' => ['call', '方法名'] ~~~ eg:比如栏目模型中: ~~~ protected $_validate =[ 'parent_id' => [ [ 'rule' =>['egt', 1], 'message' => '请选择父级导航' ], [ 'rule' => array('call', 'checkParent'), 'on' => 'edit' ] ] ]; public function checkParent($value, $rule, $data) { if ($value == $data['id'] || in_array($value, (array)menu('children', $data['id']))) { return '不能选择本栏目以及其子栏目做为父级'; } return true; } ~~~ 你需要自己准备一个方法来进行自定义验证规则,验证方法可以传入的参数共有5个(后面三个根据情况选用),依次为: * 验证数据 * 验证规则 * 全部数据(数组) return true,表示验证通过; return 字符串,表示验证失败返回错误提示信息 * * * * * ### 不验证数据 ~~~ model('User')->isValidate(false)->save($data); ~~~ 这样将不会验证数据,直接写入。 ### 获取错误信息 ~~~ $user = model('User'); $rslt = $user->save($data); if (!$rslt) { pr($user->getError()); } ~~~ * * * * * 当然,验证我们也可以完全安装TP手册来,不使用系统定义的`$validate`属性。