public function testBind() { $request = Request::instance(); Route::bind('index/blog'); Route::get('index/blog/:id', 'index/blog/read'); $result = Route::check($request, '10'); $this->assertEquals(['index', 'blog', 'read'], $result['module']); Route::bind('\\app\\index\\controller', 'namespace'); $this->assertEquals(['type' => 'method', 'method' => ['\\app\\index\\controller\\blog', 'read']], Route::check($request, 'blog/read')); Route::bind('\\app\\index\\controller\\blog', 'class'); $this->assertEquals(['type' => 'method', 'method' => ['\\app\\index\\controller\\blog', 'read']], Route::check($request, 'read')); }
/** * URL路由检测(根据PATH_INFO) * @access public * @param \think\Request $request * @param array $config * @throws Exception */ public static function route($request, array $config) { define('__INFO__', $request->pathinfo()); define('__EXT__', $request->ext()); // 检测URL禁用后缀 if ($config['url_deny_suffix'] && preg_match('/\\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) { throw new Exception('url suffix deny'); } $_SERVER['PATH_INFO'] = $request->path(); $depr = $config['pathinfo_depr']; $result = false; // 路由检测 if (APP_ROUTE_ON && !empty($config['url_route_on'])) { // 开启路由 if (!empty($config['route'])) { // 导入路由配置 Route::import($config['route']); } // 路由检测(根据路由定义返回不同的URL调度) $result = Route::check($request, $_SERVER['PATH_INFO'], $depr, !IS_CLI ? $config['url_domain_deploy'] : false); if (APP_ROUTE_MUST && false === $result && $config['url_route_must']) { // 路由无效 throw new Exception('route not define '); } } if (false === $result) { // 路由无效默认分析为模块/控制器/操作/参数...方式URL $result = Route::parseUrl($_SERVER['PATH_INFO'], $depr); } //保证$_REQUEST正常取值 $_REQUEST = array_merge($_POST, $_GET, $_COOKIE); // 注册调度机制 return $request->dispatch($result); }
/** * URL路由检测(根据PATH_INFO) * @access public * @param \think\Request $request * @param array $config * @return array * @throws \think\Exception */ public static function routeCheck($request, array $config) { $path = $request->path(); $depr = $config['pathinfo_depr']; $result = false; // 路由检测 $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on']; if ($check) { // 开启路由 if (!empty($config['route'])) { // 导入路由配置 Route::import($config['route']); } // 路由检测(根据路由定义返回不同的URL调度) $result = Route::check($request, $path, $depr, $config['url_domain_deploy']); $must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must']; if ($must && false === $result) { // 路由无效 throw new HttpException(404, 'Route Not Found'); } } if (false === $result) { // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索 $result = Route::parseUrl($path, $depr, $config['controller_auto_search']); } return $result; }
/** * URL调度 * @access public * @return void */ public static function dispatch($config) { if (isset($_GET[$config['var_pathinfo']])) { // 判断URL里面是否有兼容模式参数 $_SERVER['PATH_INFO'] = $_GET[$config['var_pathinfo']]; unset($_GET[$config['var_pathinfo']]); } elseif (IS_CLI) { // CLI模式下 index.php module/controller/action/params/... $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; } // 检测域名部署 if (!IS_CLI && isset($config['sub_domain_deploy']) && $config['sub_domain_deploy']) { Route::checkDomain(); } // 监听path_info Hook::listen('path_info'); // 分析PATHINFO信息 if (!isset($_SERVER['PATH_INFO']) && $_SERVER['SCRIPT_NAME'] != $_SERVER['PHP_SELF']) { $types = explode(',', $config['pathinfo_fetch']); foreach ($types as $type) { if (0 === strpos($type, ':')) { // 支持函数判断 $_SERVER['PATH_INFO'] = call_user_func(substr($type, 1)); break; } elseif (!empty($_SERVER[$type])) { $_SERVER['PATH_INFO'] = 0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME']) ? substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; break; } } } if (empty($_SERVER['PATH_INFO'])) { $_SERVER['PATH_INFO'] = ''; define('__INFO__', ''); define('__EXT__', ''); } else { $_SERVER['PATH_INFO'] = trim($_SERVER['PATH_INFO'], '/'); define('__INFO__', $_SERVER['PATH_INFO']); // URL后缀 define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION))); $_SERVER['PATH_INFO'] = __INFO__; if (__INFO__ && !defined('BIND_MODULE')) { if ($config['url_deny_suffix'] && preg_match('/\\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) { exit; } $paths = explode($config['pathinfo_depr'], __INFO__, 2); // 获取URL中的模块名 if ($config['require_module'] && !isset($_GET[VAR_MODULE])) { $_GET[VAR_MODULE] = array_shift($paths); $_SERVER['PATH_INFO'] = implode('/', $paths); } } // 去除URL后缀 $_SERVER['PATH_INFO'] = preg_replace($config['url_html_suffix'] ? '/\\.(' . trim($config['url_html_suffix'], '.') . ')$/i' : '/\\.' . __EXT__ . '$/i', '', $_SERVER['PATH_INFO']); } // URL常量 define('__SELF__', strip_tags($_SERVER[$config['url_request_uri']])); // 获取模块名称 define('MODULE_NAME', defined('BIND_MODULE') ? BIND_MODULE : self::getModule($config)); // 模块初始化 if (MODULE_NAME && $config['common_module'] != MODULE_NAME && is_dir(APP_PATH . MODULE_NAME)) { Hook::listen('app_begin'); define('MODULE_PATH', APP_PATH . MODULE_NAME . '/'); define('VIEW_PATH', MODULE_PATH . VIEW_LAYER . '/'); // 初始化模块 self::initModule(MODULE_PATH, $config); } 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']))); // 获取操作名 define('ACTION_NAME', strip_tags(strtolower(isset($_GET[VAR_ACTION]) ? $_GET[VAR_ACTION] : $config['default_action']))); unset($_GET[VAR_ACTION], $_GET[VAR_CONTROLLER], $_GET[VAR_MODULE]); //保证$_REQUEST正常取值 $_REQUEST = array_merge($_POST, $_GET, $_COOKIE); }
public function testBind() { Route::bind('module', 'index/blog'); $this->assertEquals(['type' => 'module', 'module' => ['index', 'blog', 'read']], Route::parseUrl('read/10')); Route::get('index/blog/:id', 'index/blog/read'); $this->assertEquals(['type' => 'module', 'module' => ['index', 'blog', 'read']], Route::check('10')); Route::bind('namespace', '\\app\\index\\controller'); $this->assertEquals(['type' => 'method', 'method' => ['\\app\\index\\controller\\blog', 'read'], 'params' => []], Route::check('blog/read')); Route::bind('class', '\\app\\index\\controller\\blog'); $this->assertEquals(['type' => 'method', 'method' => ['\\app\\index\\controller\\blog', 'read'], 'params' => []], Route::check('read')); }
/** * URL路由检测(根据PATH_INFO) * @access public * @param \think\Request $request * @param array $config * @return array * @throws \think\Exception */ public static function routeCheck($request, array $config) { $path = $request->path(); $depr = $config['pathinfo_depr']; $result = false; // 路由检测 $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on']; if ($check) { // 开启路由 if (is_file(RUNTIME_PATH . 'route.php')) { // 读取路由缓存 $rules = (include RUNTIME_PATH . 'route.php'); if (is_array($rules)) { Route::rules($rules); } } else { $files = $config['route_config_file']; foreach ($files as $file) { if (is_file(CONF_PATH . $file . CONF_EXT)) { // 导入路由配置 $rules = (include CONF_PATH . $file . CONF_EXT); if (is_array($rules)) { Route::import($rules); } } } } // 路由检测(根据路由定义返回不同的URL调度) $result = Route::check($request, $path, $depr, $config['url_domain_deploy']); $must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must']; if ($must && false === $result) { // 路由无效 throw new RouteNotFoundException(); } } if (false === $result) { // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索 $result = Route::parseUrl($path, $depr, $config['controller_auto_search']); } return $result; }