路由支持分组

默认加载公共配置文件的routes参数作为路由设置
其他规则需要自己注册
This commit is contained in:
thinkphp
2015-11-22 17:53:44 +08:00
parent fa17feddf0
commit 75f32db911
2 changed files with 101 additions and 43 deletions

View File

@@ -253,9 +253,13 @@ class App
if ($config['url_deny_suffix'] && preg_match('/\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) { if ($config['url_deny_suffix'] && preg_match('/\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) {
throw new Exception('URL_SUFFIX_DENY'); 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中的模块名 // 获取URL中的模块名
if ($config['require_module'] && !isset($_GET[VAR_MODULE])) { if ($config['require_module'] && !isset($_GET[VAR_MODULE])) {
$paths = explode($config['pathinfo_depr'], __INFO__, 2);
$_GET[VAR_MODULE] = array_shift($paths); $_GET[VAR_MODULE] = array_shift($paths);
$_SERVER['PATH_INFO'] = implode('/', $paths); $_SERVER['PATH_INFO'] = implode('/', $paths);
} }
@@ -278,8 +282,6 @@ class App
} else { } else {
throw new Exception('module not exists :' . MODULE_NAME); 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']))); define('CONTROLLER_NAME', strip_tags(strtolower(isset($_GET[VAR_CONTROLLER]) ? $_GET[VAR_CONTROLLER] : $config['default_controller'])));

View File

@@ -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, '|')) { if (strpos($type, '|')) {
foreach (explode('|', $type) as $val) { foreach (explode('|', $type) as $val) {
@@ -57,13 +57,28 @@ class Route
} else { } else {
if (is_array($rule)) { if (is_array($rule)) {
foreach ($rule as $key => $val) { foreach ($rule as $key => $val) {
if (0 === strpos($key, '[')) {
self::$rules[$type][substr($key, 1, -1)] = ['routes' => $val, 'option' => $option];
} else {
self::$rules[$type][$key] = ['route' => $val, 'option' => $option]; self::$rules[$type][$key] = ['route' => $val, 'option' => $option];
} }
}
} else {
if (0 === strpos($rule, '[')) {
self::$rules[$type][substr(substr($rule, -1), 1)] = ['routes' => $route, 'option' => $option];
} else { } else {
self::$rules[$type][$rule] = ['route' => $route, 'option' => $option]; 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 = []) public static function any($rule, $route = '', $option = [])
@@ -176,6 +191,7 @@ class Route
// URL映射 // URL映射
return self::parseUrl(self::$map[$regx]); return self::parseUrl(self::$map[$regx]);
} }
// 获取当前请求类型的路由规则 // 获取当前请求类型的路由规则
$rules = self::$rules[REQUEST_METHOD]; $rules = self::$rules[REQUEST_METHOD];
if (!empty(self::$rules['*'])) { if (!empty(self::$rules['*'])) {
@@ -185,9 +201,12 @@ class Route
// 路由规则检测 // 路由规则检测
if (!empty($rules)) { if (!empty($rules)) {
foreach ($rules as $rule => $val) { 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']) { if (isset($option['ext']) && __EXT__ != $option['ext']) {
continue; continue;
@@ -202,50 +221,87 @@ class Route
continue; continue;
} }
} }
if (!empty($val['routes'])) {
// 分组路由
if (0 !== strpos($regx, $rule)) {
continue;
}
// 匹配到路由分组
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;
}
}
}
} else {
// 单项路由
$route = $val['route'];
if (0 === strpos($rule, '/') && preg_match($rule, $regx, $matches)) { if (0 === strpos($rule, '/') && preg_match($rule, $regx, $matches)) {
// 正则路由 return self::checkRegx($route, $regx, $matches);
if (!empty($option['file'])) {
// 调度到某个文件中执行
include $route;
exit;
}
if ($route instanceof \Closure) {
// 执行闭包并中止
self::invokeRegx($route, $matches);
exit;
}
return self::parseRegex($matches, $route, $regx);
} else { } 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, '/'); $len1 = substr_count($regx, '/');
$len2 = substr_count($rule, '/'); $len2 = substr_count($rule, '/');
if ($len1 >= $len2) { if ($len1 >= $len2) {
if ('$' == substr($rule, -1, 1)) { if ('$' == substr($rule, -1, 1)) {
// 完整匹配 // 完整匹配
if ($len1 != $len2) { if ($len1 != $len2) {
continue; return false;
} else { } else {
$rule = substr($rule, 0, -1); $rule = substr($rule, 0, -1);
} }
} }
if (false !== $var = self::match($regx, $rule)) { if (false !== $match = self::match($regx, $rule)) {
if (!empty($option['file'])) {
// 调度到某个文件中执行
include $route;
exit;
}
if ($route instanceof \Closure) { if ($route instanceof \Closure) {
// 执行闭包并中止 // 执行闭包
self::invokeRule($route, $var); $result = self::invokeRule($route, $match);
exit; // 如果返回布尔值 则继续执行
return is_bool($result) ? $result : exit;
} }
return self::parseRule($rule, $route, $regx); return self::parseRule($rule, $route, $regx);
} }
} }
} return false;
}
}
return self::parseUrl($regx);
} }
/** /**