自写校验规则,在项目中常会用到各种校验。但是各个框架之间对数据校验这块又会有许多的不一样,因此我自写了一个类:
<?php
/**
* 校验数据
*/
class CheckData extends Controller {
private $ruleList;
public $defaultRequired;
public function __construct(){
$this->defaultRequired = true;//是否开启默认必选
$this->ruleList = array(
'required',#必选
'int',#整型
'float',#浮点型
'string',#字符
'gt',#大于
'gte',#大于等于
'lt',#小于
'lte',#小于等于
'minlen',#最小长度
'maxlen',#最大长度
'mobile',#手机
'ip',#ip地址
'email',#email
'in',#是否在某个范围内,范围内的子集以 *,* 分隔 如 in.1*,*2*,*3*,*4*,*5*,*6
'noin',#不在某个范围内,范围内的子集以 *,* 分隔 如 noin.1*,*2*,*3*,*4*,*5*,*6
'eq',#等于某个值
'neq',#不等于某个值
'array',#是否数组
'id',#是否为id id值必须存在,且为正整数
);
}
public function ruleCheck($data,$rule){
if (!is_array($data)){
return returnMsg('system error',10001);
}
if (!is_array($rule)){
return returnMsg('systemerror',10002);
}
// if (count($data)!=count($rule)){
// return returnMsg('systemerror',10003);
// }
if (count($data)>80){
return returnMsg('systemerror',10004);
}
foreach ($rule as $rk=>$rv){
if (!is_string($rv)){
return returnMsg('rule error',10007);
}
$check_rule_list = explode('|',(string)$rv);
if ($this->defaultRequired == true){
//校验类开启了默认必选,且用户校验无required属性
array_unshift($check_rule_list,'required');
}
foreach ($check_rule_list as $srk=>$srv){
if (strstr($srv,'.') && in_array(explode('.',$srv)[0],['gt','gte','lt','lte','minlen','maxlen','in','noin'])){
$srv_lock = explode('.',$srv)[0];
$$srv_lock = function ($key,$ruleValue,$checkValue) use ($data){
return $this->goCheck($data,$key,$ruleValue,$checkValue);
};
}else{
$srv_lock = $srv;
$$srv_lock = function ($key,$ruleValue) use ($data){
return $this->goCheck($data,$key,$ruleValue);
};
}
//规则校验开始
if (strstr($srv,'.')){
//二次规则,含 . 的方法校验
$sun_rule = explode('.',$srv);
if (!in_array($sun_rule[0],$this->ruleList) && !strstr($sun_rule[0],'Function()')){
//不在规则范围内,且非自定义校验
return returnMsg('two:no have rule '.$sun_rule[0],10006);
}
$intermediate = $sun_rule[0];//数组直接放到可变变量中会出现不可预知的错误
$check_status = $$intermediate($rk,$sun_rule[0],$sun_rule[1]);
}else{
if (!in_array($srv,$this->ruleList) && !strstr($srv,'Function()')){
return returnMsg('one:no have rule '.$srv,10006);
}
$check_status = $$srv($rk,$srv);
}
if ($check_status === true){
unset($$srv_lock);//销毁,释放
continue;
}else{
return returnMsg($check_status,400);
}
}
}
return true;
}
/**
* 校验开始
*/
private function goCheck($data,$key,$ruleValue,$checkValue=''){
if (strstr($ruleValue,'Function()')){
//自定义校验
$new_str = str_replace('Function()','',$ruleValue);
if (!function_exists($new_str)){
return $new_str.' function no set';
}else{
return $new_str($data);
}
}
if ($ruleValue!='required' && !isset($data[$key])){
//非必填,且不存在时,直接返回
return true;
}
switch ($ruleValue){
//系统校验
case 'required':
if (isset($data[$key])){
return true;
}else{
return $key.' no required';
}
break;
case 'id':
if (is_numeric($data[$key]) && ((int)($data[$key]) == $data[$key]) && $data[$key]>0){
return true;
}else{
return $key.' no id';
}
break;
case 'int':
if (is_numeric($data[$key]) && ((int)($data[$key]) == $data[$key])){
return true;
}else{
return $key.' no int';
}
break;
case 'array':
if (is_array($data[$key])){
return true;
}else{
return $key.' no array';
}
break;
case 'float':
if (is_numeric($data[$key])){
return true;
}else{
return $key.' no number';
}
break;
case 'string':
if (is_numeric($data[$key]) || is_string($data[$key])){
return true;
}else{
return $key.' no string';
}
break;
case 'gt':
if (is_numeric($data[$key]) && ($data[$key]>$checkValue)){
return true;
}else{
return $key.' no gt '.$checkValue;
}
break;
case 'gte':
if (is_numeric($data[$key]) && ($data[$key]>=$checkValue)){
return true;
}else{
return $key.' no gte '.$checkValue;
}
break;
case 'lt':
if (is_numeric($data[$key]) && ($data[$key]<$checkValue)){
return true;
}else{
return $key.' no gte '.$checkValue;
}
break;
case 'lte':
if (is_numeric($data[$key]) && ($data[$key]<=$checkValue)){
return true;
}else{
return $key.' no gte '.$checkValue;
}
break;
case 'eq':
if ($data[$key]===$checkValue){
return true;
}else{
return $key.'no eq'.$checkValue;
}
break;
case 'neq':
if ($data[$key]===$checkValue){
return $key.'no neq'.$checkValue;
}else{
return true;
}
break;
case 'minlen':
if ((is_numeric($data[$key]) || is_string($data[$key])) && (mb_strlen($data[$key])>=$checkValue)){
return true;
}else{
return $key.' a length no gte '.$checkValue;
}
break;
case 'maxlen':
if ((is_numeric($data[$key]) || is_string($data[$key])) && (mb_strlen($data[$key])<=$checkValue)){
return true;
}else{
return $key.' a length no lte '.$checkValue;
}
break;
case 'mobile':
if(is_numeric($data[$key]) && (mb_strlen($data[$key])==11) && preg_match("/^1[34578]{1}\d{9}$/",$data[$key])){
return true;
}else{
return $key.' no mobile';
}
break;
case 'ip':
//ipv4 ipv6都可
if(!is_numeric($data[$key]) && is_string($data[$key]) && filter_var($data[$key], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)){
return true;
}else{
return $key.' no ip';
}
break;
case 'email':
if (!is_numeric($data[$key]) && is_string($data[$key]) && filter_var($data[$key], FILTER_VALIDATE_EMAIL)){
return true;
}else{
return $key.' no email';
}
break;
case 'in':
$checkarr = explode('*,*',$checkValue);
if (in_array($data[$key],$checkarr)){
return true;
}else{
return $key.' no in'.str_replace('*','',implode(',',$checkarr));
}
break;
case 'noin':
$checkarr = explode('*,*',$checkValue);
if (!in_array($data[$key],$checkarr)){
return true;
}else{
return $key.' in '.str_replace('*','',implode(',',$checkarr));
}
break;
default:
return $ruleValue.' rule no set';
}
}
}
////示例
//$obj = new checkData();
//var_dump( $obj->ruleCheck(
// [
// 'username'=>'18344363446',//需要校验的数据
// 'age'=>'952323608@qq.com',//ip对局域网ip不进行通过
// 'type'=>1
// ],
// [
//
// 'username'=>'mobile|gt.10|lt.18344363447',
// 'type'=>'float|lt.1'
// ]
//));
//testFunction()为自定义校验放方法,Function()为固定后缀,test为校验的方法名
如需添加其他类型的校验或存在bug,抑或对使用不了解的,可以留言
本文介绍了一种自定义的PHP数据校验类,该类支持多种数据类型及复杂规则的校验,如整型、浮点型、字符串长度等,并支持自定义校验方法。

1623

被折叠的 条评论
为什么被折叠?



