/** * 执行检测 * * if ($validation->check()) * { * // 校验通过 * } * * @return bool */ public function check() { // 清空数据和错误 $data = $this->_errors = []; // 保存原来的数据 $original = $this->_data; // 读取字段信息 $fields = Arr::merge(array_keys($original), array_keys($this->_labels)); // 现在的规则 $rules = $this->_rules; // 逐个字段格式化下规则 foreach ($fields as $field) { $data[$field] = Arr::get($this->_data, $field); // 如果key为true,那么规则就是所有字段都生效 if (isset($rules[true])) { if (!isset($rules[$field])) { $rules[$field] = []; } $rules[$field] = array_merge($rules[$field], $rules[true]); } } // 保存格式化后的规则 $this->_data = $data; // 清空全局规则 unset($rules[true]); // 绑定一些必要的变量 $this->bind(':validation', $this); $this->bind(':data', $this->_data); foreach ($rules as $field => $set) { $value = Arr::get($this->_data, $field); // 绑定当前处理的字段和值 $this->bind([':field' => $field, ':value' => $value]); foreach ($set as $array) { // 格式:[$rule, $params] $rule = array_shift($array); $params = array_shift($array); foreach ($params as $key => $param) { // 替换绑定的变量 if (is_string($param) && array_key_exists($param, $this->_bound)) { $params[$key] = $this->_bound[$param]; } } // 默认错误名跟规则名一致,因为一般规则都是字符串表示的 $errorName = $rule; // 规则是数组,说明传入的是一个callback if (is_array($rule)) { // 允许rule('field', [':model', 'some_rule']); if (is_string($rule[0]) && array_key_exists($rule[0], $this->_bound)) { $rule[0] = $this->_bound[$rule[0]]; } // 把索引为1的值作为错误标记 $errorName = $rule[1]; $passed = call_user_func_array($rule, $params); } elseif (!is_string($rule)) { // 匿名函数不做错误处理,留待内容做处理 $errorName = false; $passed = call_user_func_array($rule, $params); } elseif (method_exists(self::$validHelperClass, $rule)) { // 调用校验助手类来完成操作 $method = new ReflectionMethod(self::$validHelperClass, $rule); $passed = $method->invokeArgs(null, $params); } elseif (false === strpos($rule, '::')) { // 不符合静态方法调用的规则,那么直接按照函数调用 $function = new ReflectionFunction($rule); $passed = $function->invokeArgs($params); } else { // 当做一次静态函数调用 $temp = explode('::', $rule, 2); $class = array_shift($temp); $method = array_shift($temp); $method = new ReflectionMethod($class, $method); $passed = $method->invokeArgs(null, $params); } if (!in_array($rule, $this->_emptyRules) && !Valid::notEmpty($value)) { continue; } if (false === $passed && false !== $errorName) { $this->error($field, $errorName, $params); break; } elseif (isset($this->_errors[$field])) { // 匿名函数自己处理错误信息,这里就不处理了 break; } } } // 还原原来的值 $this->_data = $original; return empty($this->_errors); }
/** * 根据URI创建一个新的请求对象 * * $request = new Request($uri); * * If $cache parameter is set, the response for the request will attempt to be retrieved from the cache. * * @param string $uri URI of the request * @param array $clientParams Array of params to pass to the request client * @param array $injectedRoutes An array of routes to use, for testing * @throws RequestException */ public function __construct($uri, $clientParams = [], $injectedRoutes = []) { $clientParams = is_array($clientParams) ? $clientParams : []; $this->message = new Message(); $this->routes = $injectedRoutes; $splitUri = explode('?', $uri); $uri = array_shift($splitUri); if (null !== Request::$initialRequest) { if ($splitUri) { parse_str($splitUri[0], $this->_get); } } // 要区分内部链接和外部链接 if (Valid::url($uri)) { // 为其创建一个路由 $this->route = new Entry(['uri' => $uri]); $this->uri = $uri; if (0 === strpos($uri, 'https://')) { $this->secure = true; } $this->external = true; $this->client = new ExternalClient($clientParams); Base::getLog()->debug(__METHOD__ . ' make an internal request', ['uri' => $uri, 'params' => $clientParams]); } else { $this->uri = trim($uri, '/'); $this->client = new InternalClient($clientParams); Base::getLog()->debug(__METHOD__ . ' make an external request', ['uri' => $uri, 'params' => $clientParams]); } parent::__construct(); }