think\Route::parseRule PHP Method

parseRule() private static method

解析规则路由
private static parseRule ( string $rule, string $route, string $pathinfo, array $option = [], array $matches = [] ) : array
$rule string 路由规则
$route string 路由地址
$pathinfo string URL地址
$option array 路由参数
$matches array 匹配的变量
return array
    private static function parseRule($rule, $route, $pathinfo, $option = [], $matches = [])
    {
        $request = Request::instance();
        // 解析路由规则
        if ($rule) {
            $rule = explode('/', $rule);
            // 获取URL地址中的参数
            $paths = explode('|', $pathinfo);
            foreach ($rule as $item) {
                $fun = '';
                if (0 === strpos($item, '[:')) {
                    $item = substr($item, 1, -1);
                }
                if (0 === strpos($item, ':')) {
                    $var = substr($item, 1);
                    $matches[$var] = array_shift($paths);
                } else {
                    // 过滤URL中的静态变量
                    array_shift($paths);
                }
            }
        } else {
            $paths = explode('|', $pathinfo);
        }
        // 获取路由地址规则
        if (is_string($route) && isset($option['prefix'])) {
            // 路由地址前缀
            $route = $option['prefix'] . $route;
        }
        // 替换路由地址中的变量
        if (is_string($route) && !empty($matches)) {
            foreach ($matches as $key => $val) {
                if (false !== strpos($route, ':' . $key)) {
                    $route = str_replace(':' . $key, $val, $route);
                    unset($matches[$key]);
                }
            }
        }
        // 绑定模型数据
        if (isset($option['bind_model'])) {
            $bind = [];
            foreach ($option['bind_model'] as $key => $val) {
                if ($val instanceof \Closure) {
                    $result = call_user_func_array($val, [$matches]);
                } else {
                    if (is_array($val)) {
                        $fields = explode('&', $val[1]);
                        $model = $val[0];
                        $exception = isset($val[2]) ? $val[2] : true;
                    } else {
                        $fields = ['id'];
                        $model = $val;
                        $exception = true;
                    }
                    $where = [];
                    $match = true;
                    foreach ($fields as $field) {
                        if (!isset($matches[$field])) {
                            $match = false;
                            break;
                        } else {
                            $where[$field] = $matches[$field];
                        }
                    }
                    if ($match) {
                        $query = strpos($model, '\\') ? $model::where($where) : Loader::model($model)->where($where);
                        $result = $query->failException($exception)->find();
                    }
                }
                if (!empty($result)) {
                    $bind[$key] = $result;
                }
            }
            $request->bind($bind);
        }
        // 解析额外参数
        self::parseUrlParams(empty($paths) ? '' : implode('|', $paths), $matches);
        // 记录匹配的路由信息
        $request->routeInfo(['rule' => $rule, 'route' => $route, 'option' => $option, 'var' => $matches]);
        // 检测路由after行为
        if (!empty($option['after_behavior'])) {
            if ($option['after_behavior'] instanceof \Closure) {
                $result = call_user_func_array($option['after_behavior'], []);
            } else {
                foreach ((array) $option['after_behavior'] as $behavior) {
                    $result = Hook::exec($behavior, '');
                    if (!is_null($result)) {
                        break;
                    }
                }
            }
            // 路由规则重定向
            if ($result instanceof Response) {
                return ['type' => 'response', 'response' => $result];
            } elseif (is_array($result)) {
                return $result;
            }
        }
        if ($route instanceof \Closure) {
            // 执行闭包
            $result = ['type' => 'function', 'function' => $route];
        } elseif (0 === strpos($route, '/') || strpos($route, '://')) {
            // 路由到重定向地址
            $result = ['type' => 'redirect', 'url' => $route, 'status' => isset($option['status']) ? $option['status'] : 301];
        } elseif (false !== strpos($route, '\\')) {
            // 路由到方法
            $route = str_replace('/', '@', $route);
            $method = strpos($route, '@') ? explode('@', $route) : $route;
            $result = ['type' => 'method', 'method' => $method];
        } elseif (0 === strpos($route, '@')) {
            // 路由到控制器
            $result = ['type' => 'controller', 'controller' => substr($route, 1)];
        } else {
            // 路由到模块/控制器/操作
            $result = self::parseModule($route);
        }
        // 开启请求缓存
        if ($request->isGet() && !empty($option['cache'])) {
            $cache = $option['cache'];
            if (is_array($cache)) {
                list($key, $expire) = $cache;
            } else {
                $key = $pathinfo;
                $expire = $cache;
            }
            $request->cache($key, $expire);
        }
        return $result;
    }