在批量校验字段的有效性时,有很多校验规则是可以重复利用的,这样我们可以定义一个校验类将所有校验规则都收敛到这个类中,并对外提供一个可调用的校验方法。
定义校验类
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!