From cf720bbf8cc001b3740430da4edc3db275015237 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 11 Jan 2016 18:21:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96Url=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/Route.php | 43 +++--------- library/think/Url.php | 142 +++++++++++++++++++--------------------- 2 files changed, 78 insertions(+), 107 deletions(-) diff --git a/library/think/Route.php b/library/think/Route.php index d18ea447..5bc14fa7 100644 --- a/library/think/Route.php +++ b/library/think/Route.php @@ -117,21 +117,25 @@ class Route if (empty($val)) { break; } - self::$rules[$type][substr($key, 1, -1)] = ['routes' => $val, 'option' => $option, 'pattern' => $pattern]; + $key = substr($key, 1, -1); + $result = ['routes' => $val, 'option' => $option, 'pattern' => $pattern]; } elseif (is_array($val)) { - self::$rules[$type][$key] = ['route' => $val[0], 'option' => $val[1], 'pattern' => $val[2]]; + $result = ['route' => $val[0], 'option' => $val[1], 'pattern' => $val[2]]; } else { - self::$rules[$type][$key] = ['route' => $val, 'option' => $option, 'pattern' => $pattern]; + $result = ['route' => $val, 'option' => $option, 'pattern' => $pattern]; } + self::$rules[$type][$key] = $result; } } else { if (0 === strpos($rule, '[')) { - self::$rules[$type][substr($rule, 1, -1)] = ['routes' => $route, 'option' => $option, 'pattern' => $pattern]; + $rule = substr($rule, 1, -1); + $result = ['routes' => $route, 'option' => $option, 'pattern' => $pattern]; } elseif (is_array($route)) { - self::$rules[$type][$rule] = ['route' => $route[0], 'option' => $route[1], 'pattern' => $route[2]]; + $result = ['route' => $route[0], 'option' => $route[1], 'pattern' => $route[2]]; } else { - self::$rules[$type][$rule] = ['route' => $route, 'option' => $option, 'pattern' => $pattern]; + $result = ['route' => $route, 'option' => $option, 'pattern' => $pattern]; } + self::$rules[$type][$rule] = $result; } } } @@ -625,31 +629,4 @@ class Route $_GET = array_merge($var, $_GET); } - // 根据路由别名和参数获取URL地址 - public static function getRouteUrl($name, $params = []) - { - if (strpos($name, '?')) { - // [路由别名?]参数1=值1&参数2=值2... - list($name, $params) = explode('?', $name); - } - - if (!empty(self::$alias[$name])) { - $url = self::$alias[$name]; - if (is_string($params)) { - parse_str($params, $vars); - } else { - $vars = $params; - } - foreach ($vars as $key => $val) { - if (false !== strpos($url, '[:' . $key . ']')) { - $url = str_replace('[:' . $key . ']', $val, $url); - } else { - $url = str_replace(':' . $key, $val, $url); - } - } - return $url; - } else { - return false; - } - } } diff --git a/library/think/Url.php b/library/think/Url.php index b83b63cd..3dd54458 100644 --- a/library/think/Url.php +++ b/library/think/Url.php @@ -40,24 +40,13 @@ class Url $vars = array_merge($params, $vars); } - // 检测是否存在路由别名 - if ($aliasUrl = Route::getRouteUrl($url, $vars)) { - // 存在别名定义则优先 - $url = $aliasUrl; + // 检测路由 + if ($match = self::getRouteUrl($url, $vars)) { + // 处理路由规则中的特殊内容 + $url = str_replace(['\\d', '$'], '', $match); } else { - // 检测路由 - if (false === $match = Cache::get(md5($url))) { - // 没有检测过 重新检测 - $match = self::checkRoute($url, $vars); - Cache::set(md5($url), empty($match) ? '' : $match); - } - if (!$match) { - // 路由不存在 直接解析 - $url = self::parseUrl($url); - } else { - // 处理路由规则中的特殊内容 - $url = str_replace(['\\d', '$'], '', $match); - } + // 路由不存在 直接解析 + $url = self::parseUrl($url); } // 检测URL绑定 @@ -71,17 +60,6 @@ class Url // 还原URL分隔符 $depr = Config::get('pathinfo_depr'); $url = str_replace('/', $depr, $url); - // 替换变量 - $params = []; - foreach ($vars as $key => $val) { - if (false !== strpos($url, '[:' . $key . ']')) { - $url = str_replace('[:' . $key . ']', $val, $url); - } elseif (false !== strpos($url, ':' . $key)) { - $url = str_replace(':' . $key, $val, $url); - } else { - $params[$key] = $val; - } - } // URL后缀 $suffix = self::parseSuffix($suffix); @@ -104,7 +82,7 @@ class Url } // 检测域名 - $domain = self::checkDomain($url, $domain); + $domain = self::parseDomain($url, $domain); // URL组装 $url = $domain . Config::get('base_url') . '/' . $url; @@ -137,45 +115,8 @@ class Url return $url; } - // 检测路由定义 - protected static function checkRoute($url, $vars) - { - // 获取路由定义 - $rules = Route::getRules(); - // 全局变量规则 - $pattern = Route::pattern(); - foreach ($rules as $rule => $val) { - if (!empty($val['routes'])) { - // 匹配到路由分组 - foreach ($val['routes'] as $key => $route) { - if (is_numeric($key)) { - $key = array_shift($route); - } - $check = isset($route[2]) ? array_merge($pattern, $route[2]) : $pattern; - $route = $route[0]; - $route = is_array($route) ? $route[0] : $route; - $result = $rule . Config::get('pathinfo_depr') . $key; - if ($route == $url && self::checkPattern($result, $vars, $check)) { - return $result; - } - } - } else { - if (is_numeric($rule)) { - $rule = array_shift($val); - } - $route = $val['route']; - $route = is_array($route) ? $route[0] : $route; - $check = isset($val['pattern']) ? array_merge($pattern, $val['pattern']) : $pattern; - if ($route == $url && self::checkPattern($rule, $vars, $check)) { - return $rule; - } - } - } - return false; - } - // 检测域名 - protected static function checkDomain($url, $domain) + protected static function parseDomain($url, $domain) { if ($domain) { if (true === $domain) { @@ -201,7 +142,7 @@ class Url } // 检测变量规则 - protected static function checkPattern($rule, $vars, $pattern) + protected static function pattern($rule, $vars, $pattern) { // 检测路由规则中的变量 // 检测是否设置了参数分隔符 @@ -231,12 +172,6 @@ class Url } } } - foreach ($vars as $name => $val) { - if (isset($pattern[$name]) && !preg_match('/^' . $pattern[$name] . '$/', $val)) { - // 检查变量规则 - return false; - } - } return true; } @@ -265,4 +200,63 @@ class Url } return false; } + + // 匹配路由地址 + public static function getRouteUrl($name, &$vars = []) + { + $alias = self::getRouteAlias(); + if (!empty($alias[$name])) { + foreach ($alias[$name] as $key => $url) { + // 检查变量匹配 + if (self::pattern($url, $vars, $check)) { + foreach ($vars as $key => $val) { + if (false !== strpos($url, '[:' . $key . ']')) { + $url = str_replace('[:' . $key . ']', $val, $url); + unset($vars[$key]); + } elseif (false !== strpos($url, ':' . $key)) { + $url = str_replace(':' . $key, $val, $url); + unset($vars[$key]); + } + } + return $url; + } + } + } + return false; + } + + // 自动生成路由别名 + private static function getRouteAlias() + { + if ($alias = Cache::get('think_route_alias')) { + return $alias; + } + // 获取路由定义 + $rules = Route::getRules(); + if ($rules) { + foreach ($rules as $rule => $val) { + if (!empty($val['routes'])) { + foreach ($val['routes'] as $key => $route) { + if (is_numeric($key)) { + $key = array_shift($route); + } + $route = $route[0]; + if (strpos($route, '?')) { + $route = strstr($route, '?', true); + } + $alias[$route][] = $rule . '/' . $key; + } + } else { + $route = $val['route']; + if (strpos($route, '?')) { + $route = strstr($route, '?', true); + } + $alias[$route][] = $rule; + } + } + Cache::set('think_route_alias', $alias); + return $alias; + } + return []; + } }