在批量校验字段的有效性时,有很多校验规则是可以重复利用的,这样我们可以定义一个校验类将所有校验规则都收敛到这个类中,并对外提供一个可调用的校验方法。
定义校验类
class Validator {// 长度校验const MIN_LEN = "minLen";// 取值范围校验const RANGE = "range";const POSITIVE = "positive";const NEGATIVE = "negative";const NOT_POSITIVE = "notPositive";const NOT_NEGATIVE = "notNegative";// 数据类型校验const NUMERIC = "numeric";const INT = "int";static protected $_typeMap = [self::RANGE => 'self::isInRange',self::MIN_LEN => 'self::checkMinLen',self::INT => 'self::isInt',self::POSITIVE => 'self::isPositive',self::NEGATIVE => 'self::isNegative',self::NOT_POSITIVE => 'self::isNotPositive',self::NOT_NEGATIVE => 'self::isNotNegative',self::NUMERIC => 'self::isNumeric',];public static function check($type, $v, $rule) {return call_user_func_array(self::$_typeMap[$type], [$v, $rule]);}private static function isNumeric($v, $cond) {return is_numeric($v);}private static function isInRange($v, $range) {if (!is_array($range) || count($range) != 2) {return false;}return $v >= $range[0] && $v <= $range[1];}private static function checkMinLen($v, $len) {return strlen($v) >= $len;}private static function isInt($v, $cond) {if (is_int($v)) {return true;}$i = intval($v);return "{$i}" == $v;}private static function isPositive($v, $cond) {return is_numeric($v) && intval($v) > 0;}private static function isNegative($v, $cond) {return is_numeric($v) && intval($v) < 0;}private static function isNotPositive($v, $cond) {return is_numeric($v) && intval($v) <= 0;}private static function isNotNegative($v, $cond) {return is_numeric($v) && intval($v) >= 0;}
}
定义校验方法
function checkFields($rules, $data) {foreach ($rules as $field => $fieldRules) {if (!isset($data[$field])) {echo "missing param $field \n";return false;}}foreach ($rules as $field => $fieldRules) {foreach ($fieldRules as $type => $rule) {$ret = Validator::check($type, $data[$field], $rule);if ($ret == false) {echo "param $field is invalid!\n";return false;}}}return true;
}
使用示例
- 定义多个字段的校验规则
$checkRules = array('/a/b' => ['name' => [Validator::MIN_LEN => 1,],'age' => [Validator::NOT_NEGATIVE => true,],],'/a/c' => ['orderId' => [Validator::MIN_LEN => 1,],'timestamp' => [Validator::NOT_NEGATIVE => true,],],'/a/d' => ['uid' => [Validator::MIN_LEN => 1,],'pageNo' => [Validator::NOT_NEGATIVE => true,],'pageSize' => [Validator::RANGE => [1, 1000],],],
);
- 调用校验方法对字段进行批量校验
class TestController
{function AB(){global $checkRules;$params = array('name' => 'zhoumin','age' => 0,);$ret = checkFields($checkRules['/a/b'], $params);if ($ret == false) {echo "params are invalid!\n";return;} else {echo "params are valid!\n";}}function AC(){global $checkRules;$params = array('orderId' => '330159','timestamp' => 1601234567, // 2020/9/28 3:22:47);$ret = checkFields($checkRules['/a/c'], $params);if ($ret == false) {echo "params are invalid!\n";return;} else {echo "params are valid!\n";}}function AD(){global $checkRules;$params = array('uid' => 8888,'pageNo' => 3,'pageSize' => -20,);$ret = checkFields($checkRules['/a/d'], $params);if ($ret == false) {echo "params are invalid!\n";return;} else {echo "params are valid!\n";}}
}$tc = new TestController();
$tc->AB();
$tc->AC();
$tc->AD();
- 执行结果
params are valid!
params are valid!
param pageSize is invalid!
params are invalid!