protected function buildRouteCache() { $files = \think\Config::get('route_config_file'); foreach ($files as $file) { if (is_file(CONF_PATH . $file . CONF_EXT)) { $config = (include CONF_PATH . $file . CONF_EXT); if (is_array($config)) { \think\Route::import($config); } } } $rules = \think\Route::rules(true); array_walk_recursive($rules, [$this, 'buildClosure']); $content = '<?php ' . PHP_EOL . 'return '; $content .= var_export($rules, true) . ';'; $content = str_replace(['\'[__start__', '__end__]\''], '', stripcslashes($content)); return $content; }
public function testDomain() { $request = Request::create('http://subdomain.thinkphp.cn'); Route::domain('subdomain.thinkphp.cn', 'sub?abc=test&status=1'); $rules = Route::rules('GET'); Route::checkDomain($request, $rules); $this->assertEquals('sub', Route::getbind('module')); $this->assertEquals('test', $_GET['abc']); $this->assertEquals(1, $_GET['status']); Route::domain('subdomain.thinkphp.cn', '\\app\\index\\controller'); $rules = Route::rules('GET'); Route::checkDomain($request, $rules); $this->assertEquals('\\app\\index\\controller', Route::getbind('namespace')); Route::domain(['subdomain.thinkphp.cn' => '@\\app\\index\\controller\\blog']); $rules = Route::rules('GET'); Route::checkDomain($request, $rules); $this->assertEquals('\\app\\index\\controller\\blog', Route::getbind('class')); }
/** * 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; }
/** * 路由注册 * @param string $rule 路由规则 * @param mixed $route 路由地址 * @param sting $type 请求类型 * @param array $option 路由参数 * @param array $pattern 变量规则 * @return void */ function route($rule = '', $route = [], $type = '*', $option = [], $pattern = []) { Route::rule($rule, $route, $type, $option, $pattern); }
/** * 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); }
private static function getRouteAlias() { if ($item = Cache::get('think_route_map')) { return $item; } // 获取路由定义 $array = Route::rules(); foreach ($array as $type => $rules) { foreach ($rules as $rule => $val) { if (true === $val || empty($val['rule'])) { continue; } $route = $val['route']; $vars = $val['var']; if (is_array($val['rule'])) { foreach ($val['rule'] as $val) { $key = $val['rule']; $route = $val['route']; $var = $val['var']; $param = []; if (is_array($route)) { $route = implode('\\', $route); } elseif ($route instanceof \Closure) { continue; } elseif (strpos($route, '?')) { list($route, $str) = explode('?', $route, 2); parse_str($str, $param); } $var = array_merge($vars, $var); $item[$route][] = [$rule . '/' . $key, $var, $param]; } } else { $param = []; if (is_array($route)) { $route = implode('\\', $route); } elseif ($route instanceof \Closure) { continue; } elseif (strpos($route, '?')) { list($route, $str) = explode('?', $route, 2); parse_str($str, $param); } $item[$route][] = [$rule, $vars, $param]; } } } // 检测路由别名 $alias = Route::rules('alias'); foreach ($alias as $rule => $route) { $route = is_array($route) ? $route[0] : $route; $item[$route][] = [$rule, [], []]; } !App::$debug && Cache::set('think_route_map', $item); return $item; }
public function testRoot() { Config::set('url_domain_deploy', false); Config::set('url_common_param', false); Url::root('/index.php'); Route::get('blog/:id', 'index/blog/read'); Config::set('url_html_suffix', 'shtml'); $this->assertEquals('/index.php/blog/10/name/thinkphp.shtml', Url::build('index/blog/read?id=10&name=thinkphp')); }
protected static function parseDomain(&$url, $domain) { if (!$domain) { return ''; } $request = Request::instance(); if (true === $domain) { // 自动判断域名 $domain = $request->host(); if (Config::get('url_domain_deploy')) { // 根域名 $urlDomainRoot = Config::get('url_domain_root'); $domains = Route::rules('domain'); $route_domain = array_keys($domains); foreach ($route_domain as $domain_prefix) { if (0 === strpos($domain_prefix, '*.') && strpos($domain, ltrim($domain_prefix, '*.')) !== false) { foreach ($domains as $key => $rule) { $rule = is_array($rule) ? $rule[0] : $rule; if (is_string($rule) && false === strpos($key, '*') && 0 === strpos($url, $rule)) { $url = ltrim($url, $rule); $domain = $key; // 生成对应子域名 if (!empty($urlDomainRoot)) { $domain .= $urlDomainRoot; } break; } else { if (false !== strpos($key, '*')) { if (!empty($urlDomainRoot)) { $domain .= $urlDomainRoot; } break; } } } } } } } elseif (!strpos($domain, '.')) { $rootDomain = Config::get('url_domain_root'); if (empty($rootDomain)) { $host = $request->host(); $rootDomain = substr_count($host, '.') > 1 ? substr(strstr($host, '.'), 1) : $host; } $domain .= '.' . $rootDomain; } return ($request->isSsl() ? 'https://' : 'http://') . $domain; }
public function testDomain() { $_SERVER['HTTP_HOST'] = 'subdomain.thinkphp.cn'; $_SERVER['REQUEST_URI'] = ''; Route::domain('subdomain.thinkphp.cn', 'sub?abc=test&status=1'); Route::checkDomain(); $this->assertEquals('sub?abc=test&status=1', Route::domain('subdomain.thinkphp.cn')); $this->assertEquals('sub', Route::bind('module')); $this->assertEquals('test', $_GET['abc']); $this->assertEquals(1, $_GET['status']); Route::domain('subdomain.thinkphp.cn', function () { return ['type' => 'module', 'module' => 'sub2']; }); Route::checkDomain(); $this->assertEquals('sub2', Route::bind('module')); Route::domain('subdomain.thinkphp.cn', '\\app\\index\\controller'); Route::checkDomain(); $this->assertEquals('\\app\\index\\controller', Route::bind('namespace')); Route::domain('subdomain.thinkphp.cn', '@\\app\\index\\controller\\blog'); Route::checkDomain(); $this->assertEquals('\\app\\index\\controller\\blog', Route::bind('class')); Route::domain('subdomain.thinkphp.cn', '[sub3]'); Route::checkDomain(); $this->assertEquals('sub3', Route::bind('group')); }
/** * 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; }
<?php function a2($a, $b) { return $a + $b; } \think\Route::get('getsession/:time', function ($time) { //获取session ssid $arr = array(); $ssid = md5(mt_rand(1, 999999) . time() . mt_rand(1, 999999)); $arr['ssid'] = $ssid; $arr['session_die_time'] = time() + $time; S("ssid_" . $ssid, $arr, $time); return $arr; }); \think\Hook::add('action_begin', function () { //签名验证 return; $getArr = I('get.'); if (!$getArr) { return; } $sign = isset($getArr['sign']) ? $getArr['sign'] : system_error("not_fonud_sign"); unset($getArr['sign']); ksort($getArr); $signstr = ""; foreach ($getArr as $k => $v) { $signstr .= $k . "=" . urlencode($v) . "&"; } $signstr = rtrim($signstr, "&"); if (md5($signstr) != $sign) {
public function testBuildAnchor() { Route::get('blog/:id', 'index/blog'); Config::set('url_html_suffix', 'shtml'); $this->assertEquals('/blog/10.shtml#detail', Url::build('/blog/10#detail')); }