Validator.php ':attribute field is required', 'integer' = ':attribute field must be an integer', 'float' = ':attribute field must be a float', 'numeric' = ':attribute field must be numeric', 'email' = ':attribute is not a valid email', 'alp
':attribute field is required',
'integer' => ':attribute field must be an integer',
'float' => ':attribute field must be a float',
'numeric' => ':attribute field must be numeric',
'email' => ':attribute is not a valid email',
'alpha' => ':attribute field must be an alpha value',
'alpha_numeric' => ':attribute field must be alphanumeric',
'ip' => ':attribute must contain a valid IP',
'url' => ':attribute must contain a valid URL',
'max_length' => ':attribute can be maximum :params(0) character long',
'min_length' => ':attribute must be minimum :params(0) character long',
'exact_length' => ':attribute field must :params(0) character long',
'equals' => ':attribute field should be same as :params(0)'
);
/**
* Validator constructor.
* 不能通过构造方法实例化
* @param $errors
* @param $namings
*/
private function __construct($errors, $namings) {
$this->errors = (array)$errors;
$this->namings = (array)$namings;
}
/**
* [validate 校验字段合法性]
* @param $inputs
* @param $rules
* @param int $errorCode 错误码
* @param null $naming 别名
* @return static
* @throws Exception
*/
public static function validate($inputs, $rules, $errorCode = 4001, $naming = null) {
$errors = null;
foreach ($rules as $input => $input_rules) {
//统一把规则列表当做数组来处理,单个也转化成数组,好处理
$input_rules = is_array($input_rules) ? $input_rules : array($input_rules);
foreach ($input_rules as $rule => $closure) {
if (!isset($inputs[(string)$input])) {
$input_value = null;
} else {
$input_value = $inputs[(string)$input];
}
//如果规则的key是数字,是自定义函数
if (is_numeric($rule)) {
$rule = $closure;
}
$rule_and_params = static::getParams($rule);
$params = $real_params = $rule_and_params['params'];
$rule = $rule_and_params['rule'];
$params = static::getParamValues($params, $inputs);
array_unshift($params, $input_value);
//处理匿名函数
if (is_object($closure) && get_class($closure) == 'Closure') {
$refl_func = new \ReflectionFunction($closure);
$validation = $refl_func->invokeArgs($params);
} else {
//处理类方法
if (@method_exists(get_called_class(), $rule)) {
$refl = new \ReflectionMethod(get_called_class(), $rule);
if ($refl->isStatic()) {
$refl->setAccessible(true);
$validation = $refl->invokeArgs(null, $params);
} else {
throw new Exception(str_replace(":param", $rule, "the method ':param' should be static"), self::NEED_STATIC_METHOD);
}
} else {
throw new Exception(str_replace(":param", $rule, "unknow rule: ':param'"), self::UNKNOWN_RULE_OF_PARAM);
}
}
if ($validation == false) {
$errors[(string)$input][(string)$rule]['result'] = false;
$errors[(string)$input][(string)$rule]['params'] = $real_params;
}
}
}
//return new static($errors, $naming);
$objValidate = new static($errors, $naming);
if (!$objValidate->isSuccess()) {
//JSON_UNESCAPED_UNICODE 解决中文输出乱码问题
$message = json_encode($objValidate->getErrors(), JSON_UNESCAPED_UNICODE);
throw new Exception($message, $errorCode);
}
return $objValidate;
}
/**
* [getErrors 获取错误信息]
* @return array
* @throws Exception
*/
public function getErrors() {
$error_results = array();
//默认的错误提示
$default_error_texts = self::$default_error_texts;
foreach ($this->errors as $input_name => $results) {
foreach ($results as $rule => $result) {
$named_input = $this->handleNaming($input_name);
/**
* if parameters are input name they should be named as well
*/
$result['params'] = $this->handleParameterNaming($result['params']);
// 有用户别名,应用
if (isset(self::$customErrorsWithInputName[(string)$input_name][(string)$rule])) {
$error_message = self::$customErrorsWithInputName[(string)$input_name][(string)$rule];
} else {
if (isset(self::$customErrors[(string)$rule])) {
$error_message = self::$customErrors[(string)$rule];
} else {
//默认错误信息
if (isset($default_error_texts[(string)$rule])) {
$error_message = $default_error_texts[(string)$rule];
} else {
throw new Exception(str_replace(":param", $rule, "cound not found ':param'"), self::COUND_NOT_FOUND_PARAM);
}
}
}
/**
* handle :params(..)
*/
if (preg_match_all("#:params\((.+?)\)#", $error_message, $param_indexes)) {
foreach ($param_indexes[1] as $param_index) {
$error_message = str_replace(":params(" . $param_index . ")", $result['params'][$param_index], $error_message);
}
}
//$error_results[$named_input][] = str_replace(":attribute", $named_input, $error_message);
if (!array_key_exists($named_input, $error_results)) {
//只抛出某个参数的第一条错误,过多容易引起混乱
$error_results[$named_input] = str_replace(":attribute", $named_input, $error_message);
}
}
}
return $error_results;
}
/**
* [only 只获取某些字段并返回]
* [类似其他框架的场景,支持默认值 key:val,习惯把默认值放后面]
* @param $arrSource
* @param $arrNeedle
* @return array
*/
public static function only($arrSource, $arrNeedle) {
$arrResInput = array();
$arrNeedle = is_array($arrNeedle) ? $arrNeedle : array($arrNeedle);
foreach ($arrNeedle as $needle) {
if (strpos($needle, ':')) {
$key = explode(':', $needle)[0];
//strpos 比正则效率高
$defaultVal = explode(':', $needle)[1];
$arrResInput[$key] = isset($arrSource[$key]) ? $arrSource[$key] : $defaultVal;
} else {
$arrResInput[$needle] = $arrSource[$needle];
}
}
return $arrResInput;
}
/**
* [setCustomErrors 自定义错误信息]
* @param $errors_array
* @return void
*/
public static function setCustomErrors($errors_array) {
foreach ($errors_array as $key => $value) {
// 处理参数类型 (name.required)
if (preg_match("#^(.+?)\.(.+?)$#", $key, $matches)) {
// self::$customErrorsWithInputName[name][required] = error message
self::$customErrorsWithInputName[(string)$matches[1]][(string)$matches[2]] = $value;
} else {
self::$customErrors[(string)$key] = $value;
}
}
}
/**
* [getParams 获取一条规则的参数]
* @param $rule
* @return array
*/
private static function getParams($rule) {
if (preg_match("#^([a-zA-Z0-9_]+)\((.+?)\)$#", $rule, $matches)) {
return array(
'rule' => $matches[1],
'params' => explode(",", $matches[2])
);
}
return array(
'rule' => $rule,
'params' => array()
);
}
/**
* [getParamValues ]
* @param $params
* @param $inputs
* @return mixed
*/
private static function getParamValues($params, $inputs) {
foreach ($params as $key => $param) {
if (preg_match("#^:([\[\]a-zA-Z0-9_]+)$#", $param, $param_type)) {
$params[$key] = @$inputs[(string)$param_type[1]];
}
}
return $params;
}
/**
* [handleNaming 处理别名]
* @param $input_name
* @return mixed
*/
protected function handleNaming($input_name) {
if (isset($this->namings[(string)$input_name])) {
$named_input = $this->namings[(string)$input_name];
} else {
$named_input = $input_name;
}
return $named_input;
}
/**
* [handleParameterNaming 处理参数别名]
* @param $params
* @return mixed
*/
protected function handleParameterNaming($params) {
foreach ($params as $key => $param) {
if (preg_match("#^:([a-zA-Z0-9_]+)$#", $param, $param_type)) {
if (isset($this->namings[(string)$param_type[1]])) {
$params[$key] = $this->namings[(string)$param_type[1]];
} else {
$params[$key] = $param_type[1];
}
}
}
return $params;
}
/**
* [has 参数是否有某个规则]
* @param $input_name
* @param null $rule_name
* @return bool
*/
public function has($input_name, $rule_name = null) {
if ($rule_name != null) {
return isset($this->errors[$input_name][$rule_name]);
}
return isset($this->errors[$input_name]);
}
/**
* [getResults 获取返回结果]
* @return array
*/
final public function getResults() {
return $this->errors;
}
/**
* [isSuccess 是否执行成功]
* @return bool
*/
public function isSuccess() {
return (empty($this->errors) == true);
}
/**
* [requireInArr 参数必须在数组中]
* @param $input
* @param $arr
* @return bool
*/
public static function requireInArr($input, $arr) {
return !isset($input) || !in_array($input, $arr);
}
/**
* [required 必须]
* @param null $input
* @return bool
*/
protected static function required($input = null) {
return (!is_null($input) && (trim($input) != ''));
}
/**
* [numeric 数值型]
* @param $input
* @return bool
*/
protected static function numeric($input) {
return is_numeric($input);
}
/**
* [email email规则]
* @param $input
* @return mixed
*/
protected static function email($input) {
return filter_var($input, FILTER_VALIDATE_EMAIL);
}
/**
* [integer 整数型]
* @param $input
* @return bool
*/
protected static function integer($input) {
return is_int($input) || ($input == (string)(int)$input);
}
/**
* [float 浮点型]
* @param $input
* @return bool
*/
protected static function float($input) {
return is_float($input) || ($input == (string)(float)$input);
}
/**
* [alpha 字母列表]
* @param $input
* @return bool
*/
protected static function alpha($input) {
return (preg_match("#^[a-zA-ZÀ-ÿ]+$#", $input) == 1);
}
/**
* [alpha_numeric 字母数字列表]
* @param $input
* @return bool
*/
protected static function alpha_numeric($input) {
return (preg_match("#^[a-zA-ZÀ-ÿ0-9]+$#", $input) == 1);
}
/**
* [ip ip类型]
* @param $input
* @return mixed
*/
protected static function ip($input) {
return filter_var($input, FILTER_VALIDATE_IP);
}
/**
* [url url]
* @param $input
* @return mixed
*/
protected static function url($input) {
return filter_var($input, FILTER_VALIDATE_URL);
}
/**
* [max_length 最大长度]
* @param $input
* @param $length
* @return bool
*/
protected static function max_length($input, $length) {
return (strlen($input) <= $length);
}
/**
* [min_length 最小长度]
* @param $input
* @param $length
* @return bool
*/
protected static function min_length($input, $length) {
return (strlen($input) >= $length);
}
/**
* [exact_length ]
* @param $input
* @param $length
* @return bool
*/
protected static function exact_length($input, $length) {
return (strlen($input) == $length);
}
/**
* [equals 相等检查]
* @param $input
* @param $param
* @return bool
*/
protected static function equals($input, $param) {
return ($input == $param);
}
}
