更新内核
This commit is contained in:
@@ -24,13 +24,13 @@ class Route
|
||||
{
|
||||
// 路由规则
|
||||
private static $rules = [
|
||||
'GET' => [],
|
||||
'POST' => [],
|
||||
'PUT' => [],
|
||||
'DELETE' => [],
|
||||
'PATCH' => [],
|
||||
'HEAD' => [],
|
||||
'OPTIONS' => [],
|
||||
'get' => [],
|
||||
'post' => [],
|
||||
'put' => [],
|
||||
'delete' => [],
|
||||
'patch' => [],
|
||||
'head' => [],
|
||||
'options' => [],
|
||||
'*' => [],
|
||||
'alias' => [],
|
||||
'domain' => [],
|
||||
@@ -40,21 +40,22 @@ class Route
|
||||
|
||||
// REST路由操作方法定义
|
||||
private static $rest = [
|
||||
'index' => ['GET', '', 'index'],
|
||||
'create' => ['GET', '/create', 'create'],
|
||||
'edit' => ['GET', '/:id/edit', 'edit'],
|
||||
'read' => ['GET', '/:id', 'read'],
|
||||
'save' => ['POST', '', 'save'],
|
||||
'update' => ['PUT', '/:id', 'update'],
|
||||
'delete' => ['DELETE', '/:id', 'delete'],
|
||||
'index' => ['get', '', 'index'],
|
||||
'create' => ['get', '/create', 'create'],
|
||||
'edit' => ['get', '/:id/edit', 'edit'],
|
||||
'read' => ['get', '/:id', 'read'],
|
||||
'save' => ['post', '', 'save'],
|
||||
'update' => ['put', '/:id', 'update'],
|
||||
'delete' => ['delete', '/:id', 'delete'],
|
||||
];
|
||||
|
||||
// 不同请求类型的方法前缀
|
||||
private static $methodPrefix = [
|
||||
'GET' => 'get',
|
||||
'POST' => 'post',
|
||||
'PUT' => 'put',
|
||||
'DELETE' => 'delete',
|
||||
'get' => 'get',
|
||||
'post' => 'post',
|
||||
'put' => 'put',
|
||||
'delete' => 'delete',
|
||||
'patch' => 'patch',
|
||||
];
|
||||
|
||||
// 子域名
|
||||
@@ -68,6 +69,8 @@ class Route
|
||||
private static $domainRule;
|
||||
// 当前域名
|
||||
private static $domain;
|
||||
// 当前路由执行过程中的参数
|
||||
private static $option = [];
|
||||
|
||||
/**
|
||||
* 注册变量规则
|
||||
@@ -126,7 +129,7 @@ class Route
|
||||
* 设置路由绑定
|
||||
* @access public
|
||||
* @param mixed $bind 绑定信息
|
||||
* @param string $type 绑定类型 默认为module 支持 namespace class
|
||||
* @param string $type 绑定类型 默认为module 支持 namespace class controller
|
||||
* @return mixed
|
||||
*/
|
||||
public static function bind($bind, $type = 'module')
|
||||
@@ -148,8 +151,9 @@ class Route
|
||||
} elseif ('' === $name) {
|
||||
return self::$rules['name'];
|
||||
} elseif (!is_null($value)) {
|
||||
self::$rules['name'][$name][] = $value;
|
||||
self::$rules['name'][strtolower($name)][] = $value;
|
||||
} else {
|
||||
$name = strtolower($name);
|
||||
return isset(self::$rules['name'][$name]) ? self::$rules['name'][$name] : null;
|
||||
}
|
||||
}
|
||||
@@ -198,7 +202,7 @@ class Route
|
||||
unset($rule['__rest__']);
|
||||
}
|
||||
|
||||
self::registerRules($rule, strtoupper($type));
|
||||
self::registerRules($rule, strtolower($type));
|
||||
}
|
||||
|
||||
// 批量注册路由
|
||||
@@ -241,7 +245,7 @@ class Route
|
||||
$pattern = array_merge(self::getGroup('pattern'), $pattern);
|
||||
}
|
||||
|
||||
$type = strtoupper($type);
|
||||
$type = strtolower($type);
|
||||
|
||||
if (strpos($type, '|')) {
|
||||
$option['method'] = $type;
|
||||
@@ -300,12 +304,12 @@ class Route
|
||||
$rule = substr($rule, 0, -1);
|
||||
}
|
||||
|
||||
if ('/' != $rule) {
|
||||
if ('/' != $rule || $group) {
|
||||
$rule = trim($rule, '/');
|
||||
}
|
||||
$vars = self::parseVar($rule);
|
||||
if (isset($name)) {
|
||||
$key = $group ? $group . '/' . $rule : $rule;
|
||||
$key = $group ? $group . ($rule ? '/' . $rule : '') : $rule;
|
||||
self::name($name, [$key, $vars, self::$domain]);
|
||||
}
|
||||
if ($group) {
|
||||
@@ -328,7 +332,7 @@ class Route
|
||||
}
|
||||
if ('*' == $type) {
|
||||
// 注册路由快捷方式
|
||||
foreach (['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'] as $method) {
|
||||
foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) {
|
||||
if (self::$domain) {
|
||||
self::$rules['domain'][self::$domain][$method][$rule] = true;
|
||||
} else {
|
||||
@@ -339,6 +343,27 @@ class Route
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前执行的参数信息
|
||||
* @access public
|
||||
* @param array $options 参数信息
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function setOption($options = [])
|
||||
{
|
||||
self::$option[] = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前执行的所有参数信息
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public static function getOption()
|
||||
{
|
||||
return self::$option;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的分组信息
|
||||
* @access public
|
||||
@@ -423,15 +448,16 @@ class Route
|
||||
$options['complete_match'] = true;
|
||||
$key = substr($key, 0, -1);
|
||||
}
|
||||
$key = trim($key, '/');
|
||||
$vars = self::parseVar($key);
|
||||
$item[] = ['rule' => $key, 'route' => $route, 'var' => $vars, 'option' => $options, 'pattern' => $patterns];
|
||||
// 设置路由标识
|
||||
self::name($route, [$name . '/' . $key, $vars, self::$domain]);
|
||||
self::name($route, [$name . ($key ? '/' . $key : ''), $vars, self::$domain]);
|
||||
}
|
||||
self::$rules['*'][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern];
|
||||
}
|
||||
|
||||
foreach (['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'] as $method) {
|
||||
foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) {
|
||||
if (!isset(self::$rules[$method][$name])) {
|
||||
self::$rules[$method][$name] = true;
|
||||
} elseif (is_array(self::$rules[$method][$name])) {
|
||||
@@ -576,7 +602,8 @@ class Route
|
||||
} elseif (strpos($val[1], ':id') && isset($option['var'][$rule])) {
|
||||
$val[1] = str_replace(':id', ':' . $option['var'][$rule], $val[1]);
|
||||
}
|
||||
$item = ltrim($rule . $val[1], '/');
|
||||
$item = ltrim($rule . $val[1], '/');
|
||||
$option['rest'] = $key;
|
||||
self::rule($item . '$', $route . '/' . $val[2], $val[0], $option, $pattern);
|
||||
}
|
||||
}
|
||||
@@ -625,9 +652,9 @@ class Route
|
||||
public static function setMethodPrefix($method, $prefix = '')
|
||||
{
|
||||
if (is_array($method)) {
|
||||
self::$methodPrefix = array_merge(self::$methodPrefix, array_change_key_case($method, CASE_UPPER));
|
||||
self::$methodPrefix = array_merge(self::$methodPrefix, array_change_key_case($method));
|
||||
} else {
|
||||
self::$methodPrefix[strtoupper($method)] = $prefix;
|
||||
self::$methodPrefix[strtolower($method)] = $prefix;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,7 +662,7 @@ class Route
|
||||
* rest方法定义和修改
|
||||
* @access public
|
||||
* @param string $name 方法名称
|
||||
* @param array $resourece 资源
|
||||
* @param array $resource 资源
|
||||
* @return void
|
||||
*/
|
||||
public static function rest($name, $resource = [])
|
||||
@@ -682,7 +709,7 @@ class Route
|
||||
if (is_array($rules)) {
|
||||
self::$rules = $rules;
|
||||
} elseif ($rules) {
|
||||
return true === $rules ? self::$rules : self::$rules[$rules];
|
||||
return true === $rules ? self::$rules : self::$rules[strtolower($rules)];
|
||||
} else {
|
||||
$rules = self::$rules;
|
||||
unset($rules['pattern'], $rules['alias'], $rules['domain'], $rules['name']);
|
||||
@@ -698,7 +725,7 @@ class Route
|
||||
* @param string $method 请求类型
|
||||
* @return void
|
||||
*/
|
||||
public static function checkDomain($request, &$currentRules, $method = 'GET')
|
||||
public static function checkDomain($request, &$currentRules, $method = 'get')
|
||||
{
|
||||
// 域名规则
|
||||
$rules = self::$rules['domain'];
|
||||
@@ -808,7 +835,7 @@ class Route
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
$method = $request->method();
|
||||
$method = strtolower($request->method());
|
||||
// 获取当前请求类型的路由规则
|
||||
$rules = self::$rules[$method];
|
||||
// 检测域名部署
|
||||
@@ -823,14 +850,16 @@ class Route
|
||||
if ('|' != $url) {
|
||||
$url = rtrim($url, '|');
|
||||
}
|
||||
if (isset($rules[$url])) {
|
||||
$item = str_replace('|', '/', $url);
|
||||
if (isset($rules[$item])) {
|
||||
// 静态路由规则检测
|
||||
$rule = $rules[$url];
|
||||
$rule = $rules[$item];
|
||||
if (true === $rule) {
|
||||
$rule = self::getRouteExpress($url);
|
||||
$rule = self::getRouteExpress($item);
|
||||
}
|
||||
if (!empty($rule['route']) && self::checkOption($rule['option'], $request)) {
|
||||
return self::parseRule($url, $rule['route'], $url, $rule['option']);
|
||||
self::setOption($rule['option']);
|
||||
return self::parseRule($item, $rule['route'], $url, $rule['option']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -893,7 +922,7 @@ class Route
|
||||
if (is_string($str) && $str && 0 !== strpos(str_replace('|', '/', $url), $str)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
self::setOption($option);
|
||||
$result = self::checkRoute($request, $rule, $url, $depr, $key, $option);
|
||||
if (false !== $result) {
|
||||
return $result;
|
||||
@@ -908,6 +937,8 @@ class Route
|
||||
if ($group) {
|
||||
$rule = $group . ($rule ? '/' . ltrim($rule, '/') : '');
|
||||
}
|
||||
|
||||
self::setOption($option);
|
||||
if (isset($options['bind_model']) && isset($option['bind_model'])) {
|
||||
$option['bind_model'] = array_merge($options['bind_model'], $option['bind_model']);
|
||||
}
|
||||
@@ -994,6 +1025,9 @@ class Route
|
||||
case 'class':
|
||||
// 绑定到类
|
||||
return self::bindToClass($url, $bind, $depr);
|
||||
case 'controller':
|
||||
// 绑定到控制器类
|
||||
return self::bindToController($url, $bind, $depr);
|
||||
case 'namespace':
|
||||
// 绑定到命名空间
|
||||
return self::bindToNamespace($url, $bind, $depr);
|
||||
@@ -1038,7 +1072,7 @@ class Route
|
||||
if (!empty($array[2])) {
|
||||
self::parseUrlParams($array[2]);
|
||||
}
|
||||
return ['type' => 'method', 'method' => [$namespace . '\\' . $class, $method]];
|
||||
return ['type' => 'method', 'method' => [$namespace . '\\' . Loader::parseName($class, 1), $method]];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1088,12 +1122,16 @@ class Route
|
||||
*/
|
||||
private static function checkOption($option, $request)
|
||||
{
|
||||
// 请求类型检测
|
||||
if ((isset($option['method']) && is_string($option['method']) && false === stripos($option['method'], $request->method()))
|
||||
|| (isset($option['ext']) && false === stripos($option['ext'], $request->ext())) // 伪静态后缀检测
|
||||
|| (isset($option['ajax']) && $option['ajax'] && !$request->isAjax()) // Ajax检测
|
||||
|| (isset($option['ajax']) && !$option['ajax'] && $request->isAjax()) // 非Ajax检测
|
||||
|| (isset($option['pjax']) && $option['pjax'] && !$request->isPjax()) // Pjax检测
|
||||
|| (isset($option['pjax']) && !$option['pjax'] && $request->isPjax()) // 非Pjax检测
|
||||
|| (isset($option['ext']) && false === stripos($option['ext'], $request->ext())) // 伪静态后缀检测
|
||||
|| (isset($option['deny_ext']) && false !== stripos($option['deny_ext'], $request->ext()))
|
||||
|| (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名检测
|
||||
|| (!empty($option['https']) && !$request->isSsl()) // https检测
|
||||
|| (isset($option['https']) && $option['https'] && !$request->isSsl()) // https检测
|
||||
|| (isset($option['https']) && !$option['https'] && $request->isSsl()) // https检测
|
||||
|| (!empty($option['before_behavior']) && false === Hook::exec($option['before_behavior'])) // 行为检测
|
||||
|| (!empty($option['callback']) && is_callable($option['callback']) && false === call_user_func($option['callback'])) // 自定义检测
|
||||
) {
|
||||
@@ -1161,8 +1199,9 @@ class Route
|
||||
{
|
||||
|
||||
if (isset(self::$bind['module'])) {
|
||||
$bind = str_replace('/', $depr, self::$bind['module']);
|
||||
// 如果有模块/控制器绑定
|
||||
$url = self::$bind['module'] . '/' . ltrim($url, '/');
|
||||
$url = $bind . ('.' != substr($bind, -1) ? $depr : '') . ltrim($url, $depr);
|
||||
}
|
||||
$url = str_replace($depr, '|', $url);
|
||||
list($path, $var) = self::parseUrlPath($url);
|
||||
@@ -1175,15 +1214,24 @@ class Route
|
||||
$dir = APP_PATH . ($module ? $module . DS : '') . Config::get('url_controller_layer');
|
||||
$suffix = App::$suffix || Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';
|
||||
$item = [];
|
||||
$find = false;
|
||||
foreach ($path as $val) {
|
||||
$item[] = array_shift($path);
|
||||
if (is_file($dir . DS . $val . $suffix . EXT)) {
|
||||
$item[] = $val;
|
||||
$file = $dir . DS . str_replace('.', DS, $val) . $suffix . EXT;
|
||||
$file = pathinfo($file, PATHINFO_DIRNAME) . DS . Loader::parseName(pathinfo($file, PATHINFO_FILENAME), 1) . EXT;
|
||||
if (is_file($file)) {
|
||||
$find = true;
|
||||
break;
|
||||
} else {
|
||||
$dir .= DS . $val;
|
||||
}
|
||||
}
|
||||
$controller = implode('.', $item);
|
||||
if ($find) {
|
||||
$controller = implode('.', $item);
|
||||
$path = array_slice($path, count($item));
|
||||
} else {
|
||||
$controller = array_shift($path);
|
||||
}
|
||||
} else {
|
||||
// 解析控制器
|
||||
$controller = !empty($path) ? array_shift($path) : null;
|
||||
@@ -1194,8 +1242,15 @@ class Route
|
||||
self::parseUrlParams(empty($path) ? '' : implode('|', $path));
|
||||
// 封装路由
|
||||
$route = [$module, $controller, $action];
|
||||
if (isset(self::$rules['name'][implode($depr, $route)])) {
|
||||
throw new HttpException(404, 'invalid request:' . $url);
|
||||
// 检查地址是否被定义过路由
|
||||
$name = strtolower($module . '/' . Loader::parseName($controller, 1) . '/' . $action);
|
||||
$name2 = '';
|
||||
if (empty($module) || isset($bind) && $module == $bind) {
|
||||
$name2 = strtolower(Loader::parseName($controller, 1) . '/' . $action);
|
||||
}
|
||||
|
||||
if (isset(self::$rules['name'][$name]) || isset(self::$rules['name'][$name2])) {
|
||||
throw new HttpException(404, 'invalid request:' . str_replace('|', $depr, $url));
|
||||
}
|
||||
}
|
||||
return ['type' => 'module', 'module' => $route];
|
||||
@@ -1285,9 +1340,16 @@ class Route
|
||||
if (!$optional && !isset($m1[$key])) {
|
||||
return false;
|
||||
}
|
||||
if (isset($m1[$key]) && isset($pattern[$name]) && !preg_match('/^' . $pattern[$name] . '$/', $m1[$key])) {
|
||||
if (isset($m1[$key]) && isset($pattern[$name])) {
|
||||
// 检查变量规则
|
||||
return false;
|
||||
if ($pattern[$name] instanceof \Closure) {
|
||||
$result = call_user_func_array($pattern[$name], [$m1[$key]]);
|
||||
if (false === $result) {
|
||||
return false;
|
||||
}
|
||||
} elseif (!preg_match('/^' . $pattern[$name] . '$/', $m1[$key])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$var[$name] = isset($m1[$key]) ? $m1[$key] : '';
|
||||
} elseif (!isset($m1[$key]) || 0 !== strcasecmp($val, $m1[$key])) {
|
||||
@@ -1343,7 +1405,6 @@ class Route
|
||||
foreach ($matches as $key => $val) {
|
||||
if (false !== strpos($route, ':' . $key)) {
|
||||
$route = str_replace(':' . $key, $val, $route);
|
||||
unset($matches[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1430,7 +1491,7 @@ class Route
|
||||
$result = self::parseModule($route);
|
||||
}
|
||||
// 开启请求缓存
|
||||
if ($request->isGet() && !empty($option['cache'])) {
|
||||
if ($request->isGet() && isset($option['cache'])) {
|
||||
$cache = $option['cache'];
|
||||
if (is_array($cache)) {
|
||||
list($key, $expire) = $cache;
|
||||
|
||||
Reference in New Issue
Block a user