From 75f32db911d6e08b10ad26bd56bfa682c6819471 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 22 Nov 2015 17:53:44 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E6=94=AF=E6=8C=81=E5=88=86?= =?UTF-8?q?=E7=BB=84=20=E9=BB=98=E8=AE=A4=E5=8A=A0=E8=BD=BD=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E7=9A=84routes?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E4=BD=9C=E4=B8=BA=E8=B7=AF=E7=94=B1=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=20=E5=85=B6=E4=BB=96=E8=A7=84=E5=88=99=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E8=87=AA=E5=B7=B1=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/app.php | 8 ++- library/think/route.php | 136 ++++++++++++++++++++++++++++------------ 2 files changed, 101 insertions(+), 43 deletions(-) diff --git a/library/think/app.php b/library/think/app.php index e131405f..df219b08 100644 --- a/library/think/app.php +++ b/library/think/app.php @@ -253,9 +253,13 @@ class App if ($config['url_deny_suffix'] && preg_match('/\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) { throw new Exception('URL_SUFFIX_DENY'); } - $paths = explode($config['pathinfo_depr'], __INFO__, 2); + // 路由检测 + Route::register($config['routes']); + Route::check($_SERVER['PATH_INFO'], $config['pathinfo_depr']); + // 获取URL中的模块名 if ($config['require_module'] && !isset($_GET[VAR_MODULE])) { + $paths = explode($config['pathinfo_depr'], __INFO__, 2); $_GET[VAR_MODULE] = array_shift($paths); $_SERVER['PATH_INFO'] = implode('/', $paths); } @@ -278,8 +282,6 @@ class App } else { throw new Exception('module not exists :' . MODULE_NAME); } - // 路由检测和控制器、操作解析 - Route::check($_SERVER['PATH_INFO'], $config['pathinfo_depr']); // 获取控制器名 define('CONTROLLER_NAME', strip_tags(strtolower(isset($_GET[VAR_CONTROLLER]) ? $_GET[VAR_CONTROLLER] : $config['default_controller']))); diff --git a/library/think/route.php b/library/think/route.php index fcf28581..a20e9641 100644 --- a/library/think/route.php +++ b/library/think/route.php @@ -48,7 +48,7 @@ class Route } // 注册路由规则 - public static function register($rule, $route = '', $type = 'GET', $option = []) + public static function register($rule, $route = '', $type = '*', $option = []) { if (strpos($type, '|')) { foreach (explode('|', $type) as $val) { @@ -57,14 +57,29 @@ class Route } else { if (is_array($rule)) { foreach ($rule as $key => $val) { - self::$rules[$type][$key] = ['route' => $val, 'option' => $option]; + if (0 === strpos($key, '[')) { + self::$rules[$type][substr($key, 1, -1)] = ['routes' => $val, 'option' => $option]; + } else { + self::$rules[$type][$key] = ['route' => $val, 'option' => $option]; + } } } else { - self::$rules[$type][$rule] = ['route' => $route, 'option' => $option]; + if (0 === strpos($rule, '[')) { + self::$rules[$type][substr(substr($rule, -1), 1)] = ['routes' => $route, 'option' => $option]; + } else { + self::$rules[$type][$rule] = ['route' => $route, 'option' => $option]; + } + } } } + // 路由分组 + public static function group($name, $routes = [], $type='*',$option = []) + { + self::$rules[$type][$name] = ['routes' => $routes, 'option' => $option]; + } + // 注册任意请求的路由规则 public static function any($rule, $route = '', $option = []) { @@ -176,6 +191,7 @@ class Route // URL映射 return self::parseUrl(self::$map[$regx]); } + // 获取当前请求类型的路由规则 $rules = self::$rules[REQUEST_METHOD]; if (!empty(self::$rules['*'])) { @@ -185,9 +201,12 @@ class Route // 路由规则检测 if (!empty($rules)) { foreach ($rules as $rule => $val) { - $route = $val['route']; - $option = $val['option']; + $option = $val['option']; + // 请求类型检测 + if (isset($option['method']) && REQUEST_METHOD != strtoupper($option['method'])) { + continue; + } // 伪静态后缀检测 if (isset($option['ext']) && __EXT__ != $option['ext']) { continue; @@ -202,52 +221,89 @@ class Route continue; } } - if (0 === strpos($rule, '/') && preg_match($rule, $regx, $matches)) { - // 正则路由 - if (!empty($option['file'])) { - // 调度到某个文件中执行 - include $route; - exit; + + if (!empty($val['routes'])) { + // 分组路由 + if (0 !== strpos($regx, $rule)) { + continue; } - if ($route instanceof \Closure) { - // 执行闭包并中止 - self::invokeRegx($route, $matches); - exit; - } - return self::parseRegex($matches, $route, $regx); - } else { - // 规则路由 - $len1 = substr_count($regx, '/'); - $len2 = substr_count($rule, '/'); - if ($len1 >= $len2) { - if ('$' == substr($rule, -1, 1)) { - // 完整匹配 - if ($len1 != $len2) { - continue; - } else { - $rule = substr($rule, 0, -1); + // 匹配到路由分组 + foreach ($val['routes'] as $key => $route) { + $regx1 = substr($regx, strlen($rule) + 1); + if (0 === strpos($key, '/') && preg_match($key, $regx1, $matches)) { + // 检查正则路由 + return self::checkRegx($route, $regx1, $matches); + } else { + // 检查规则路由 + $result = self::checkRule($key, $route, $regx1); + if (false !== $result) { + return $result; } } - if (false !== $var = self::match($regx, $rule)) { - if (!empty($option['file'])) { - // 调度到某个文件中执行 - include $route; - exit; - } - if ($route instanceof \Closure) { - // 执行闭包并中止 - self::invokeRule($route, $var); - exit; - } - return self::parseRule($rule, $route, $regx); + } + } else { + // 单项路由 + $route = $val['route']; + if (0 === strpos($rule, '/') && preg_match($rule, $regx, $matches)) { + return self::checkRegx($route, $regx, $matches); + } else { + // 规则路由 + $result = self::checkRule($rule, $route, $regx); + if (false !== $result) { + return $result; } } } + } } return self::parseUrl($regx); } + /** + * 检查正则路由 + */ + private function checkRegx($route, $regx, $matches) + { + // 正则路由 + if ($route instanceof \Closure) { + // 执行闭包 + $result = self::invokeRegx($route, $matches); + // 如果返回布尔值 则继续执行 + return is_bool($result) ? $result : exit; + } + return self::parseRegex($matches, $route, $regx); + } + + /** + * 检查规则路由 + */ + private function checkRule($rule, $route, $regx) + { + $len1 = substr_count($regx, '/'); + $len2 = substr_count($rule, '/'); + if ($len1 >= $len2) { + if ('$' == substr($rule, -1, 1)) { + // 完整匹配 + if ($len1 != $len2) { + return false; + } else { + $rule = substr($rule, 0, -1); + } + } + if (false !== $match = self::match($regx, $rule)) { + if ($route instanceof \Closure) { + // 执行闭包 + $result = self::invokeRule($route, $match); + // 如果返回布尔值 则继续执行 + return is_bool($result) ? $result : exit; + } + return self::parseRule($rule, $route, $regx); + } + } + return false; + } + /** * 判断是否SSL协议 * @return boolean