内核更新升级

This commit is contained in:
2016-06-27 17:49:19 +08:00
parent f9c34a87f1
commit 56fd9ee760
19 changed files with 563 additions and 584 deletions

View File

@@ -123,19 +123,26 @@ class Route
}
/**
* 设置和读取路由绑定
* 设置路由绑定
* @access public
* @param string $type 请求类型
* @param mixed $bind 绑定信息
* @param string $type 绑定类型 默认为module
* @return mixed
*/
public static function bind($type, $bind = '')
public static function bind($bind, $type = 'module')
{
if ('' == $bind) {
return isset(self::$bind[$type]) ? self::$bind[$type] : null;
} else {
self::$bind = ['type' => $type, $type => $bind];
}
self::$bind = ['type' => $type, $type => $bind];
}
/**
* 读取路由绑定
* @access public
* @param string $type 绑定类型
* @return mixed
*/
public static function getBind($type)
{
return isset(self::$bind[$type]) ? self::$bind[$type] : null;
}
/**
@@ -210,8 +217,8 @@ class Route
*/
public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = [], $group = '')
{
$group = $group ?: self::$group;
$type = strtoupper($type);
$group = $group ?: self::$group;
$type = strtoupper($type);
if (strpos($type, '|')) {
foreach (explode('|', $type) as $val) {
self::rule($rule, $route, $val, $option, $pattern, $group);
@@ -497,11 +504,12 @@ class Route
* @param string $route 路由地址
* @param string $method 请求类型
* @param array $option 路由参数
* @param string $group 路由分组
* @return void
*/
public static function miss($route, $method = '*', $option = [])
public static function miss($route, $method = '*', $option = [], $group = '')
{
self::rule('__miss__', $route, $method, $option, []);
self::rule('__miss__', $route, $method, $option, [], $group);
}
/**
@@ -522,7 +530,7 @@ class Route
/**
* 检测子域名部署
* @access public
* @param Request $request Request请求对象
* @param Request $request Request请求对象
* @return void
*/
public static function checkDomain($request)
@@ -648,13 +656,13 @@ class Route
// 路由不匹配
} elseif (0 === strpos($rule, '\\')) {
// 路由到类
return self::bindToClass($array[1], substr($rule, 1));
return self::bindToClass($array[1], substr($rule, 1), $depr);
} elseif (0 === strpos($url, '@')) {
// 路由到控制器类
return self::bindToController($array[1], substr($rule, 1));
return self::bindToController($array[1], substr($rule, 1), $depr);
} else {
// 路由到模块/控制器
return self::bindToModule($array[1], $rule);
return self::bindToModule($array[1], $rule, $depr);
}
}
@@ -671,18 +679,13 @@ class Route
self::checkDomain($request);
}
// 检测URL绑定
$return = self::checkUrlBind($url, $rules);
$return = self::checkUrlBind($url, $rules, $depr);
if ($return) {
return $return;
}
// 路由规则检测
if (!empty($rules)) {
if (isset($rules['__miss__'])) {
// 指定未匹配路由的处理
$miss = $rules['__miss__'];
unset($rules['__miss__']);
}
foreach ($rules as $rule => $val) {
$option = isset($val['option']) ? $val['option'] : [];
$pattern = isset($val['pattern']) ? $val['pattern'] : [];
@@ -691,7 +694,11 @@ class Route
if (!self::checkOption($option, $url, $request)) {
continue;
}
if ('__miss__' == $rule) {
// 指定分组MISS路由
$miss = $val['route'];
continue;
}
if (!empty($val['routes'])) {
// 分组路由
if (($pos = strpos($rule, ':')) || ($pos = strpos($rule, '<'))) {
@@ -702,13 +709,12 @@ class Route
if (0 !== strpos($url, $str)) {
continue;
}
$missGroup = false;
// 匹配到路由分组
foreach ($val['routes'] as $key => $route) {
if (is_numeric($key)) {
$key = array_shift($route);
}
$key = $rule . ($key ? '/' . ltrim($key, '/') : '');
// 检查规则路由
if (is_array($route)) {
$option1 = $route[1];
@@ -720,12 +726,27 @@ class Route
$route = $route[0];
$option = array_merge($option, $option1);
}
if ('__miss__' == $key) {
// 指定分组MISS路由
$missGroup = $route;
continue;
}
$key = $rule . ($key ? '/' . ltrim($key, '/') : '');
$result = self::checkRule($key, $route, $url, $pattern, $option);
if (false !== $result) {
$request->route(['rule' => $key, 'route' => $route, 'pattern' => $pattern, 'option' => $option]);
return $result;
}
}
if ($missGroup) {
// 未匹配所有路由的路由规则处理
if ($missGroup instanceof \Closure) {
// 执行闭包
return ['type' => 'function', 'function' => $missGroup, 'params' => []];
} else {
return self::parseRule('', $missGroup, $url, []);
}
}
} else {
if (is_numeric($rule)) {
$rule = array_shift($val);
@@ -742,11 +763,11 @@ class Route
}
if (isset($miss)) {
// 未匹配所有路由的路由规则处理
if ($miss['route'] instanceof \Closure) {
if ($miss instanceof \Closure) {
// 执行闭包
return ['type' => 'function', 'function' => $miss['route'], 'params' => []];
} elseif (self::checkOption($miss['option'], $url, $request)) {
return self::parseRule('', $miss['route'], $url, []);
return ['type' => 'function', 'function' => $miss, 'params' => []];
} else {
return self::parseRule('', $miss, $url, []);
}
}
}
@@ -758,9 +779,10 @@ class Route
* @access private
* @param string $url URL地址
* @param array $rules 路由规则
* @param string $depr URL分隔符
* @return false
*/
private static function checkUrlBind(&$url, &$rules)
private static function checkUrlBind(&$url, &$rules, $depr = '/')
{
if (!empty(self::$bind['type'])) {
// 记录绑定信息
@@ -769,10 +791,10 @@ class Route
switch (self::$bind['type']) {
case 'class':
// 绑定到类
return self::bindToClass($url, self::$bind['class']);
return self::bindToClass($url, self::$bind['class'], $depr);
case 'namespace':
// 绑定到命名空间
return self::bindToNamespace($url, self::$bind['namespace']);
return self::bindToNamespace($url, self::$bind['namespace'], $depr);
case 'module':
// 如果有模块/控制器绑定 针对路由到 模块/控制器 有效
$url = self::$bind['module'] . '/' . $url;
@@ -793,15 +815,17 @@ class Route
* @access public
* @param string $url URL地址
* @param string $class 类名(带命名空间)
* @param string $depr URL分隔符
* @return array
*/
public static function bindToClass($url, $class)
public static function bindToClass($url, $class, $depr = '/')
{
$array = explode('/', $url, 2);
$array = explode($depr, $url, 2);
$action = !empty($array[0]) ? $array[0] : Config::get('default_action');
if (!empty($array[1])) {
self::parseUrlParams($array[1]);
}
return ['type' => 'method', 'method' => [$class, $array[0] ?: Config::get('default_action')], 'params' => []];
return ['type' => 'method', 'method' => [$class, $action], 'params' => []];
}
/**
@@ -809,11 +833,12 @@ class Route
* @access public
* @param string $url URL地址
* @param string $namespace 命名空间
* @param string $depr URL分隔符
* @return array
*/
public static function bindToNamespace($url, $namespace)
public static function bindToNamespace($url, $namespace, $depr = '/')
{
$array = explode('/', $url, 3);
$array = explode($depr, $url, 3);
$class = !empty($array[0]) ? $array[0] : Config::get('default_controller');
$method = !empty($array[1]) ? $array[1] : Config::get('default_action');
if (!empty($array[2])) {
@@ -822,21 +847,43 @@ class Route
return ['type' => 'method', 'method' => [$namespace . '\\' . $class, $method], 'params' => []];
}
/**
* 绑定到应用 直接进行控制器类库访问
* @access public
* @param string $url URL地址
* @param string $depr URL分隔符
* @return array
*/
public static function bindToApp($url, $depr = '/')
{
$array = explode($depr, $url, 4);
$module = !empty($array[0]) ? $array[0] : Config::get('default_module');
$controller = !empty($array[1]) ? $array[1] : Config::get('default_controller');
$method = !empty($array[2]) ? $array[2] : Config::get('default_action');
$layer = Config::get('url_controller_layer');
$class = App::$namespace . '\\' . $module . '\\' . $layer . '\\' . $controller;
if (!empty($array[3])) {
self::parseUrlParams($array[3]);
}
return ['type' => 'method', 'method' => [$class, $method], 'params' => []];
}
/**
* 绑定到控制器类
* @access public
* @param string $url URL地址
* @param string $module 模块名
* @param string $controller 控制器名 (支持带模块名 index/user
* @param string $depr URL分隔符
* @return array
*/
public static function bindToController($url, $controller)
public static function bindToController($url, $controller, $depr = '/')
{
$array = explode('/', $url, 2);
$array = explode($depr, $url, 2);
$action = !empty($array[0]) ? $array[0] : Config::get('default_action');
if (!empty($array[1])) {
self::parseUrlParams($array[1]);
}
return ['type' => 'method', 'method' => [$controller, $action], 'params' => []];
return ['type' => 'controller', 'controller' => $controller . '/' . $action, 'params' => []];
}
/**
@@ -844,11 +891,12 @@ class Route
* @access public
* @param string $url URL地址
* @param string $class 控制器类名(带命名空间)
* @param string $depr URL分隔符
* @return array
*/
public static function bindToModule($url, $controller)
public static function bindToModule($url, $controller, $depr = '/')
{
$array = explode('/', $url, 2);
$array = explode($depr, $url, 2);
$action = !empty($array[0]) ? $array[0] : Config::get('default_action');
if (!empty($array[1])) {
self::parseUrlParams($array[1]);
@@ -883,8 +931,8 @@ class Route
* 检测路由规则
* @access private
* @param string $rule 路由规则
* @param string $url URL地址
* @param string $route 路由地址
* @param string $url URL地址
* @param array $pattern 变量规则
* @param array $option 路由参数
* @return array|false
@@ -910,7 +958,7 @@ class Route
if ($len1 >= $len2 || strpos($rule, '[')) {
if ('$' == substr($rule, -1, 1)) {
// 完整匹配
if (!$merge && $len1 != $len2 && false === strpos($rule, '[')) {
if (!$merge && $len1 != $len2 && (false === strpos($rule, '[') || $len1 > $len2 || $len1 < $len2 - substr_count($rule, '['))) {
return false;
} else {
$rule = substr($rule, 0, -1);
@@ -924,12 +972,12 @@ class Route
if ($option['after_behavior'] instanceof \Closure) {
$result = call_user_func_array($option['after_behavior'], [$route]);
} else {
foreach((array)$option['after_behavior'] as $behavior){
foreach ((array) $option['after_behavior'] as $behavior) {
$result = Hook::exec($behavior, '', $route);
if (!is_null($result)) {
break;
}
}
}
}
// 路由规则重定向
if ($result instanceof Response) {
@@ -954,10 +1002,9 @@ class Route
* @param string $url URL地址
* @param string $depr URL分隔符
* @param bool $autoSearch 是否自动深度搜索控制器
* @param integer $paramType URL参数解析方式 0 名称解析 1 顺序解析
* @return array
*/
public static function parseUrl($url, $depr = '/', $autoSearch = false, $paramType = 0)
public static function parseUrl($url, $depr = '/', $autoSearch = false)
{
if (isset(self::$bind['module'])) {
// 如果有模块/控制器绑定
@@ -968,24 +1015,46 @@ class Route
$url = str_replace($depr, '/', $url);
}
$result = self::parseRoute($url, $autoSearch, true, $paramType);
if (!empty($result['var'])) {
$_GET = array_merge($result['var'], $_GET);
list($path, $var) = self::parseUrlPath($url);
$route = [null, null, null];
if (isset($path)) {
// 解析模块
$module = Config::get('app_multi_module') ? array_shift($path) : null;
if ($autoSearch) {
// 自动搜索控制器
$dir = APP_PATH . ($module ? $module . DS : '') . 'controller';
$suffix = App::$suffix || Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';
$item = [];
foreach ($path as $val) {
$item[] = array_shift($path);
if (is_file($dir . DS . $val . $suffix . EXT)) {
break;
} else {
$dir .= DS . $val;
}
}
$controller = implode('.', $item);
} else {
// 解析控制器
$controller = !empty($path) ? array_shift($path) : null;
}
// 解析操作
$action = !empty($path) ? array_shift($path) : null;
// 解析额外参数
self::parseUrlParams(empty($path) ? '' : implode('/', $path));
// 封装路由
$route = [$module, $controller, $action];
}
return ['type' => 'module', 'module' => $result['route']];
return ['type' => 'module', 'module' => $route];
}
/**
* 解析规范的路由地址 地址格式 [模块/控制器/操作?]参数1=值1&参数2=值2...
* 解析URL的pathinfo参数和变量
* @access private
* @param string $url URL地址
* @param bool $autoSearch 是否自动深度搜索控制器
* @param bool $reverse 是否反转解析URL
* @param integer $paramType URL参数解析方式 0 名称解析 1 顺序解析
* @return array
*/
private static function parseRoute($url, $autoSearch = false, $reverse = false, $paramType = 0)
private static function parseUrlPath($url)
{
$url = trim($url, '/');
$var = [];
@@ -1003,58 +1072,7 @@ class Route
} else {
$path = [$url];
}
$route = [null, null, null];
if (isset($path)) {
if ($reverse) {
// 解析模块
$module = Config::get('app_multi_module') ? array_shift($path) : null;
if ($autoSearch) {
// 自动搜索控制器
$dir = APP_PATH . ($module ? $module . DS : '') . 'controller';
$suffix = App::$suffix || Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';
$item = [];
foreach ($path as $val) {
$item[] = array_shift($path);
if (is_file($dir . DS . $val . $suffix . EXT)) {
break;
} else {
$dir .= DS . $val;
}
}
$controller = implode('.', $item);
} else {
// 解析控制器
$controller = !empty($path) ? array_shift($path) : null;
}
// 解析操作
$action = !empty($path) ? array_shift($path) : null;
// 解析额外参数
if (!empty($path)) {
if ($paramType) {
$var += $path;
} else {
preg_replace_callback('/([^\/]+)\/([^\/]+)/', function ($match) use (&$var) {
$var[strtolower($match[1])] = strip_tags($match[2]);
}, implode('/', $path));
}
}
} else {
$action = array_pop($path);
$controller = !empty($path) ? array_pop($path) : null;
$module = Config::get('app_multi_module') && !empty($path) ? array_pop($path) : null;
$method = Request::instance()->method();
// REST 操作方法支持
if ('[rest]' == $action) {
$action = $method;
} elseif (Config::get('use_action_prefix') && !empty(self::$methodPrefix[$method])) {
// 操作方法前缀支持
$action = 0 !== strpos($action, self::$methodPrefix[$method]) ? self::$methodPrefix[$method] . $action : $action;
}
}
// 封装路由
$route = [$module, $controller, $action];
}
return ['route' => $route, 'var' => $var];
return [$path, $var];
}
/**
@@ -1166,14 +1184,22 @@ class Route
// 路由到控制器
$result = ['type' => 'controller', 'controller' => substr($url, 1), 'params' => $matches];
} else {
// 解析路由地址
$result = self::parseRoute($url);
$var = array_merge($matches, $result['var']);
// 解析剩余的URL参数
self::parseUrlParams(implode('/', $paths), $var);
// 路由到模块/控制器/操作
$result = ['type' => 'module', 'module' => $result['route'], 'convert' => false];
list($path, $var) = self::parseUrlPath($url);
$action = array_pop($path);
$controller = !empty($path) ? array_pop($path) : null;
$module = Config::get('app_multi_module') && !empty($path) ? array_pop($path) : null;
$method = Request::instance()->method();
if (Config::get('use_action_prefix') && !empty(self::$methodPrefix[$method])) {
// 操作方法前缀支持
$action = 0 !== strpos($action, self::$methodPrefix[$method]) ? self::$methodPrefix[$method] . $action : $action;
}
$_GET = array_merge($_GET, $var);
// 路由到模块/控制器/操作
$result = ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => false];
}
// 解析额外参数
self::parseUrlParams(empty($paths) ? '' : implode('/', $paths), $matches);
return $result;
}
@@ -1191,11 +1217,10 @@ class Route
$var += explode('/', $url);
} else {
preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) {
$var[strtolower($match[1])] = strip_tags($match[2]);
$var[$match[1]] = strip_tags($match[2]);
}, $url);
}
}
// 设置当前请求的参数
Request::instance()->param(array_merge($var, $_GET));
}