内核更新
This commit is contained in:
@@ -59,10 +59,10 @@ class Route
|
||||
private static $subDomain = '';
|
||||
// 域名绑定
|
||||
private static $bind = [];
|
||||
// 当前分组
|
||||
private static $group = '';
|
||||
// 当前参数
|
||||
private static $option = [];
|
||||
// 当前分组信息
|
||||
private static $group = [];
|
||||
// 路由命名标识(用于快速URL生成)
|
||||
private static $name = [];
|
||||
|
||||
/**
|
||||
* 注册变量规则
|
||||
@@ -108,6 +108,21 @@ class Route
|
||||
self::$bind = ['type' => $type, $type => $bind];
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置路由绑定
|
||||
* @access public
|
||||
* @param string $name 路由命名标识
|
||||
* @return string|array
|
||||
*/
|
||||
public static function name($name = '')
|
||||
{
|
||||
if ('' === $name) {
|
||||
return self::$name;
|
||||
} else {
|
||||
return isset(self::$name[$name]) ? self::$name[$name] : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取路由绑定
|
||||
* @access public
|
||||
@@ -160,10 +175,9 @@ class Route
|
||||
if (empty($val)) {
|
||||
continue;
|
||||
}
|
||||
if (0 === strpos($key, '[')) {
|
||||
if (is_string($key) && 0 === strpos($key, '[')) {
|
||||
$key = substr($key, 1, -1);
|
||||
self::group($key, $val);
|
||||
|
||||
} elseif (is_array($val)) {
|
||||
self::setRule($key, $val[0], $type, $val[1], isset($val[2]) ? $val[2] : []);
|
||||
} else {
|
||||
@@ -184,15 +198,20 @@ class Route
|
||||
*/
|
||||
public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = [])
|
||||
{
|
||||
$group = self::$group;
|
||||
$option = array_merge(self::$option, $option);
|
||||
$type = strtoupper($type);
|
||||
$group = self::getGroup('name');
|
||||
if (!is_null($group)) {
|
||||
// 路由分组
|
||||
$option = array_merge(self::getGroup('option'), $option);
|
||||
$pattern = array_merge(self::getGroup('pattern'), $pattern);
|
||||
}
|
||||
|
||||
$type = strtoupper($type);
|
||||
|
||||
if (strpos($type, '|')) {
|
||||
$option['method'] = $type;
|
||||
$type = '*';
|
||||
}
|
||||
if (is_array($rule)) {
|
||||
if (is_array($rule) && empty($route)) {
|
||||
foreach ($rule as $key => $val) {
|
||||
if (is_numeric($key)) {
|
||||
$key = array_shift($val);
|
||||
@@ -225,6 +244,9 @@ class Route
|
||||
*/
|
||||
protected static function setRule($rule, $route, $type = '*', $option = [], $pattern = [], $group = '')
|
||||
{
|
||||
if (is_array($rule)) {
|
||||
list($name, $rule) = $rule;
|
||||
}
|
||||
if ('$' == substr($rule, -1, 1)) {
|
||||
// 是否完整匹配
|
||||
$option['complete_match'] = true;
|
||||
@@ -234,6 +256,9 @@ class Route
|
||||
$rule = trim($rule, '/');
|
||||
}
|
||||
$vars = self::parseVar($rule);
|
||||
if (isset($name)) {
|
||||
self::$name[$name] = [$rule, $vars];
|
||||
}
|
||||
if ($group) {
|
||||
self::$rules[$type][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern];
|
||||
} else {
|
||||
@@ -251,29 +276,33 @@ class Route
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前的路由分组
|
||||
* 获取当前的分组信息
|
||||
* @access public
|
||||
* @param array $option 路由参数
|
||||
* @return void
|
||||
* @param string $type 分组信息名称 name option pattern
|
||||
* @return mixed
|
||||
*/
|
||||
public static function setGroup($name)
|
||||
public static function getGroup($type)
|
||||
{
|
||||
if (self::$group) {
|
||||
self::$group = self::$group . '/' . ltrim($name, '/');
|
||||
if (isset(self::$group[$type])) {
|
||||
return self::$group[$type];
|
||||
} else {
|
||||
self::$group = $name;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前的路由参数
|
||||
* 设置当前的路由分组
|
||||
* @access public
|
||||
* @param array $option 路由参数
|
||||
* @param string $name 分组名称
|
||||
* @param array $option 分组路由参数
|
||||
* @param array $pattern 分组变量规则
|
||||
* @return void
|
||||
*/
|
||||
public static function setOption($option)
|
||||
public static function setGroup($name, $option = [], $pattern = [])
|
||||
{
|
||||
self::$option = $option;
|
||||
self::$group['name'] = $name;
|
||||
self::$group['option'] = $option ?: [];
|
||||
self::$group['pattern'] = $pattern ?: [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,29 +311,31 @@ class Route
|
||||
* @param string|array $name 分组名称或者参数
|
||||
* @param array|\Closure $routes 路由地址
|
||||
* @param array $option 路由参数
|
||||
* @param string $type 请求类型
|
||||
* @param array $pattern 变量规则
|
||||
* @return void
|
||||
*/
|
||||
public static function group($name, $routes, $option = [], $type = '*', $pattern = [])
|
||||
public static function group($name, $routes, $option = [], $pattern = [])
|
||||
{
|
||||
if (is_array($name)) {
|
||||
$option = $name;
|
||||
$name = isset($option['name']) ? $option['name'] : '';
|
||||
}
|
||||
$type = strtoupper($type);
|
||||
if (!empty($name)) {
|
||||
// 分组
|
||||
if ($routes instanceof \Closure) {
|
||||
$curentGroup = self::$group;
|
||||
self::setGroup($name);
|
||||
$currentGroup = self::getGroup('name');
|
||||
if ($currentGroup) {
|
||||
$name = $currentGroup . '/' . ltrim($name, '/');
|
||||
}
|
||||
$currentOption = self::getGroup('option');
|
||||
$currentPattern = self::getGroup('pattern');
|
||||
self::setGroup($name, $option, $pattern);
|
||||
call_user_func_array($routes, []);
|
||||
self::$group = $curentGroup;
|
||||
|
||||
self::$rules[$type][$name]['route'] = '';
|
||||
self::$rules[$type][$name]['var'] = self::parseVar($name);
|
||||
self::$rules[$type][$name]['option'] = $option;
|
||||
self::$rules[$type][$name]['pattern'] = $pattern;
|
||||
self::setGroup($currentGroup, $currentOption, $currentPattern);
|
||||
self::$rules['*'][$name]['route'] = '';
|
||||
self::$rules['*'][$name]['var'] = self::parseVar($name);
|
||||
self::$rules['*'][$name]['option'] = $option;
|
||||
self::$rules['*'][$name]['pattern'] = $pattern;
|
||||
|
||||
} else {
|
||||
foreach ($routes as $key => $val) {
|
||||
@@ -321,26 +352,29 @@ class Route
|
||||
$vars = self::parseVar($key);
|
||||
$item[] = ['rule' => $key, 'route' => $route, 'var' => $vars, 'option' => isset($option1) ? $option1 : $option, 'pattern' => isset($pattern1) ? $pattern1 : $pattern];
|
||||
}
|
||||
self::$rules[$type][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern];
|
||||
self::$rules['*'][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern];
|
||||
}
|
||||
if ('*' == $type) {
|
||||
foreach (['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'] as $method) {
|
||||
if (!isset(self::$rules[$method][$name])) {
|
||||
self::$rules[$method][$name] = true;
|
||||
} else {
|
||||
self::$rules[$method][$name] = array_merge(self::$rules['*'][$name], self::$rules[$method][$name]);
|
||||
}
|
||||
|
||||
foreach (['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'] as $method) {
|
||||
if (!isset(self::$rules[$method][$name])) {
|
||||
self::$rules[$method][$name] = true;
|
||||
} else {
|
||||
self::$rules[$method][$name] = array_merge(self::$rules['*'][$name], self::$rules[$method][$name]);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if ($routes instanceof \Closure) {
|
||||
// 闭包注册
|
||||
self::setOption($option);
|
||||
$currentGroup = self::getGroup('name');
|
||||
$currentOption = self::getGroup('option');
|
||||
$currentPattern = self::getGroup('pattern');
|
||||
self::setGroup($name, $option, $pattern);
|
||||
call_user_func_array($routes, []);
|
||||
self::setOption([]);
|
||||
self::setGroup($currentGroup, $currentOption, $currentPattern);
|
||||
} else {
|
||||
// 批量注册路由
|
||||
self::rule($routes, '', $type, $option, $pattern);
|
||||
self::rule($routes, '', '*', $option, $pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -470,7 +504,7 @@ class Route
|
||||
$val[1] = str_replace(':id', ':' . $option['var'][$rule], $val[1]);
|
||||
}
|
||||
$item = ltrim($rule . $val[1], '/');
|
||||
self::rule($item ? $item . '$' : '', $route . '/' . $val[2], $val[0], $option, $pattern);
|
||||
self::rule($item . '$', $route . '/' . $val[2], $val[0], $option, $pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -650,16 +684,16 @@ class Route
|
||||
|
||||
if (0 === strpos($result, '\\')) {
|
||||
// 绑定到命名空间 例如 \app\index\behavior
|
||||
self::$bind = ['type' => 'namespace', 'namespace' => $result];
|
||||
self::$bind = ['type' => 'namespace', 'namespace' => $result, 'domain' => true];
|
||||
} elseif (0 === strpos($result, '@')) {
|
||||
// 绑定到类 例如 \app\index\controller\User
|
||||
self::$bind = ['type' => 'class', 'class' => substr($result, 1)];
|
||||
// 绑定到类 例如 @app\index\controller\User
|
||||
self::$bind = ['type' => 'class', 'class' => substr($result, 1), 'domain' => true];
|
||||
} elseif (0 === strpos($result, '[')) {
|
||||
// 绑定到分组 例如 [user]
|
||||
self::$bind = ['type' => 'group', 'group' => substr($result, 1, -1)];
|
||||
self::$bind = ['type' => 'group', 'group' => substr($result, 1, -1), 'domain' => true];
|
||||
} else {
|
||||
// 绑定到模块/控制器 例如 index/user
|
||||
self::$bind = ['type' => 'module', 'module' => $result];
|
||||
self::$bind = ['type' => 'module', 'module' => $result, 'domain' => true];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -701,14 +735,18 @@ class Route
|
||||
if (false !== $return) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
if ('/' != $url) {
|
||||
$url = rtrim($url, '/');
|
||||
}
|
||||
if (isset($rules[$url])) {
|
||||
// 静态路由规则检测
|
||||
$rule = $rules[$url];
|
||||
if (true === $rule) {
|
||||
$rule = self::$rules['*'][$url];
|
||||
}
|
||||
return self::parseRule($url, $rule['route'], $url, $rule['option']);
|
||||
if (!empty($rule['route'])) {
|
||||
return self::parseRule($url, $rule['route'], $url, $rule['option']);
|
||||
}
|
||||
}
|
||||
|
||||
// 路由规则检测
|
||||
@@ -733,6 +771,9 @@ class Route
|
||||
if (true === $item) {
|
||||
$item = self::$rules['*'][$key];
|
||||
}
|
||||
if (!isset($item['rule'])) {
|
||||
continue;
|
||||
}
|
||||
$rule = $item['rule'];
|
||||
$route = $item['route'];
|
||||
$vars = $item['var'];
|
||||
@@ -751,7 +792,7 @@ class Route
|
||||
} else {
|
||||
$str = $key;
|
||||
}
|
||||
if (0 !== strpos($url, $str)) {
|
||||
if (is_string($str) && 0 !== strpos($url, $str)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -759,7 +800,7 @@ class Route
|
||||
if (false !== $result) {
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
} elseif ($route) {
|
||||
if ('__miss__' == $rule) {
|
||||
// 指定MISS路由
|
||||
$miss = $item;
|
||||
@@ -838,13 +879,18 @@ class Route
|
||||
return self::bindToNamespace($url, self::$bind['namespace'], $depr);
|
||||
case 'module':
|
||||
// 如果有模块/控制器绑定 针对路由到 模块/控制器 有效
|
||||
$url = self::$bind['module'] . '/' . $url;
|
||||
$url = (empty(self::$bind['domain']) ? self::$bind['module'] . '/' : '') . ltrim($url, '/');
|
||||
break;
|
||||
case 'group':
|
||||
// 绑定到路由分组
|
||||
$key = self::$bind['group'];
|
||||
if (array_key_exists($key, $rules)) {
|
||||
$rules = [$key => $rules[self::$bind['group']]];
|
||||
$item = $rules[self::$bind['group']];
|
||||
if (!empty(self::$bind['domain']) && true === $item) {
|
||||
$rules = [self::$rules['*'][$key]];
|
||||
} else {
|
||||
$rules = [$key => $item];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1089,7 +1135,8 @@ class Route
|
||||
foreach ($m2 as $key => $val) {
|
||||
// val中定义了多个变量 <id><name>
|
||||
if (false !== strpos($val, '<') && preg_match_all('/<(\w+(\??))>/', $val, $matches)) {
|
||||
$value = [];
|
||||
$value = [];
|
||||
$replace = [];
|
||||
foreach ($matches[1] as $name) {
|
||||
if (strpos($name, '?')) {
|
||||
$name = substr($name, 0, -1);
|
||||
@@ -1128,7 +1175,7 @@ class Route
|
||||
return false;
|
||||
}
|
||||
$var[$name] = isset($m1[$key]) ? $m1[$key] : '';
|
||||
} elseif (0 !== strcasecmp($val, $m1[$key])) {
|
||||
} elseif (!isset($m1[$key]) || 0 !== strcasecmp($val, $m1[$key])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1191,32 +1238,35 @@ class Route
|
||||
$paths = explode('/', $pathinfo);
|
||||
}
|
||||
// 获取路由地址规则
|
||||
$url = $route;
|
||||
if (is_string($route) && isset($option['prefix'])) {
|
||||
// 路由地址前缀
|
||||
$route = $option['prefix'] . $route;
|
||||
}
|
||||
// 替换路由地址中的变量
|
||||
if (is_string($url) && !empty($matches)) {
|
||||
if (is_string($route) && !empty($matches)) {
|
||||
foreach ($matches as $key => $val) {
|
||||
if (false !== strpos($url, ':' . $key)) {
|
||||
$url = str_replace(':' . $key, $val, $url);
|
||||
if (false !== strpos($route, ':' . $key)) {
|
||||
$route = str_replace(':' . $key, $val, $route);
|
||||
unset($matches[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($url instanceof \Closure) {
|
||||
if ($route instanceof \Closure) {
|
||||
// 执行闭包
|
||||
$result = ['type' => 'function', 'function' => $url, 'params' => $matches];
|
||||
} elseif (0 === strpos($url, '/') || 0 === strpos($url, 'http')) {
|
||||
$result = ['type' => 'function', 'function' => $route, 'params' => $matches];
|
||||
} elseif (0 === strpos($route, '/') || 0 === strpos($route, 'http')) {
|
||||
// 路由到重定向地址
|
||||
$result = ['type' => 'redirect', 'url' => $url, 'status' => isset($option['status']) ? $option['status'] : 301];
|
||||
} elseif (0 === strpos($url, '\\')) {
|
||||
$result = ['type' => 'redirect', 'url' => $route, 'status' => isset($option['status']) ? $option['status'] : 301];
|
||||
} elseif (0 === strpos($route, '\\')) {
|
||||
// 路由到方法
|
||||
$method = strpos($url, '@') ? explode('@', $url) : $url;
|
||||
$method = strpos($route, '@') ? explode('@', $route) : $route;
|
||||
$result = ['type' => 'method', 'method' => $method, 'params' => $matches];
|
||||
} elseif (0 === strpos($url, '@')) {
|
||||
} elseif (0 === strpos($route, '@')) {
|
||||
// 路由到控制器
|
||||
$result = ['type' => 'controller', 'controller' => substr($url, 1), 'params' => $matches];
|
||||
$result = ['type' => 'controller', 'controller' => substr($route, 1), 'params' => $matches];
|
||||
} else {
|
||||
// 路由到模块/控制器/操作
|
||||
$result = self::parseModule($url);
|
||||
$result = self::parseModule($route);
|
||||
}
|
||||
// 解析额外参数
|
||||
self::parseUrlParams(empty($paths) ? '' : implode('/', $paths), $matches);
|
||||
|
||||
Reference in New Issue
Block a user