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); } }