<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] * * * * * ## 1 路由 ### 1 路由流程概覽 ![](https://box.kancloud.cn/2016-03-17_56ea7a2e4c156.jpg) ### 2 路由的意義 >[info] url作為一種輸入的數據 > 通過路由解析, > 匹配到應用業務控制器 ### 3 框架路由解析 框架路由主要關注**url的path_info部分規則解析**。 **將url中的path_info解析到對應模塊/控制器/操作** 使用**think\Route.php注冊url的path_info到對應業務的映射規則** 路由配置文件application/module/**route.php** **配置url的path_info到對應業務的映射規則** 客戶端發送url請求服務器的框架時 **在think\App.php的run()方法中調用App::route()** 根據**route.php配置文件**與使用**think\Route.php注冊的映射規則** 將**url**的path_info解析到\application的應用業務**\模塊\控制器\操作** ## 2 路由規則配置convention.php,route.php ### 全局配置參數 ~~~ thinkphp/convention.php: path_info字符串標志,path_info兼容內容,path_info分隔符 'var_pathinfo' => 's', 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], 'pathinfo_depr' => '/', 系統變量request_uri,系統變量base_url 'url_request_uri' => 'REQUEST_URI', 'base_url' => $_SERVER["SCRIPT_NAME"], 偽靜態后綴,普通方式參數?,禁止訪問后綴 'url_html_suffix' => '.html', 'url_common_param' => false, 'url_deny_suffix' => 'ico|png|gif|jpg', 路由開啟與關閉,強制路由開啟與關閉,模塊映射 'url_route_on' => true, 'url_route_must' => false, 'url_module_map' => [], 域名部署開啟與關閉,根域名 'url_domain_deploy' => false, 'url_domain_root' => '', 控制器自動轉換開啟與關閉,操作自動轉換開啟與關閉 'url_controller_convert' => true, 'url_action_convert' => true, ~~~ ### 應用路由配置 ~~~ application/route.php: return [ name變量規則定義 '__pattern__' => [ 'name' => '\w+', ], hello/:id映射規則定義 '[hello]' => [ ':id' => ['index/hello', ['method' => 'get'], ['id' => '\d+']], ':name' => ['index/hello', ['method' => 'post']], ], ]; ~~~ ### 自定義路由配置簡單示例 ~~~ return [ 'hello/:id'=>'index/hello', ] ~~~ index.php/hello/2 映射到 默認模塊的Index.php的hello() ~~~ 'blog/:id' => ['Blog/read', ['method' => 'get'], ['id' => '\d+']], 'blog/:name' => ['Blog/read', ['method' => 'post']], ~~~ index.php/blog/2 映射到 默認模塊的Blog.php的read() ## 3 框架路由解析App.php ### 1 App::run() 路由解析入口 ~~~ App::run() if (empty(self::$dispatch['type'])) { self::route($config); } ~~~ 調用self::route()根據配置參數$config解析url ### 2 App::route() Url路由解析 ~~~ self::parsePathinfo($config); ~~~ 調用**App::parsePathinfo()**根據配置參數$config解析url ~~~ if (empty($_SERVER['PATH_INFO'])) { $_SERVER['PATH_INFO'] = ''; define('__INFO__', ''); define('__EXT__', ''); } ~~~ 獲取path_info失敗時,執行如上語句。 獲取path_info成功時,執行如下語句。 `$_SERVER['PATH_INFO'] = trim($_SERVER['PATH_INFO'], '/');` 去除path_info的首尾的'/'字符 `define('__INFO__', $_SERVER['PATH_INFO']);` 定義全局常量`__INFO__`為path_info `define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION)));` 定義全局常量`__EXT__ `為path_info后綴 ~~~ if ($config['url_deny_suffix'] && preg_match('/\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) { throw new Exception('url suffix deny'); } ~~~ 這里的$config['url_deny_suffix']為convention.php中的 `'url_deny_suffix' => 'ico|png|gif|jpg',` 如果匹配成功,則拋出異常,禁止訪問。 `$_SERVER['PATH_INFO'] = preg_replace($config['url_html_suffix'] ? '/\.(' . trim($config['url_html_suffix'], '.') . ')$/i' : '/\.' . __EXT__ . '$/i', '', __INFO__);` url后綴處理,好復雜的感覺。 `$depr = $config['pathinfo_depr'];` 這里的$config['pathinfo_depr']為convention.php中的 `'pathinfo_depr' => '/',` `$result = false;` 下面的路由檢查結果保存變量。 `if (APP_ROUTE_ON && !empty($config['url_route_on'])){} ` `APP_ROUTE_ON` 在base.php中定義為true,表示開啟路由 $config['url_route_on']為convention.php中的 `'url_route_on' => true,` 定義了2個開關?? 開啟路由時 ~~~ if (!empty($config['route'])) { Route::register($config['route']); } ~~~ 檢查是否有配置路由, 如果有調用**Route::register()**進行路由規則注冊 `$result = Route::check($_SERVER['PATH_INFO'], $depr, !IS_CLI ? $config['url_domain_deploy'] : false);` 調用**Route::check()**進行path_info的分析。 ~~~ if (APP_ROUTE_MUST && false === $result && $config['url_route_must']) { throw new Exception('route not define '); } ~~~ 檢查是否開啟強制路由解析, 如果獲取解析結果失敗,在強制路由下,拋出異常 ~~~ if (false === $result) { $result = Route::parseUrl($_SERVER['PATH_INFO'], $depr); } ~~~ 沒有開啟路由檢查時,調用**Route::parseUrl()**解析path_info `self::dispatch($result);` 將路由解析解析注冊到調度類型$dispatch中 ### 3 App::parsePathinfo() path_info解析 ~~~ if (isset($_GET[$config['var_pathinfo']])) { $_SERVER['PATH_INFO'] = $_GET[$config['var_pathinfo']]; unset($_GET[$config['var_pathinfo']]); } ~~~ 這里$config['var_pathinfo']是全局配置convention.php中的 `'var_pathinfo' => 's',` 獲取$_GET['s'],即index.php?s=module/controller/action/中的s對應值 ~~~ elseif (IS_CLI) { $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; } ~~~ CLI模式下index.php module/controller/action/params/ 設置path_info的信息為 module/controller/action/params/ `APP_HOOK && Hook::listen('path_info');` path_info解析前回調處理 ~~~ if (!isset($_SERVER['PATH_INFO'])) { foreach ($config['pathinfo_fetch'] as $type) { if (!empty($_SERVER[$type])) { $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ? substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; break; } } } ~~~ 這里的$config['pathinfo_fetch']為convention.php的 `'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],` 如果path_info獲取失敗,則查找$config['pathinfo_fetch']信息 將查找到的信息添加到path_info中。 >[info] App::parsePathinfo()主要用來獲取path_info > 并保存到$_SERVER['PATH_INFO'],然后返回self::route() ### 4 App::dispatch() 注冊調度類型 `self::$dispatch = $dispatch;` 設置調度類型信息。 在**App::run()**下面根據調度類型進行應用調度 ## 4 路由解析函數Route.php ### 1 Route::check() 路由檢查入口 `public static function check($url, $depr = '/', $checkDomain = false)` > $url:待解析url > $depr:url分隔符 > $checkDomain:是否進行域名解析 ~~~ if ($checkDomain) { self::checkDomain(); } ~~~ 如果開啟域名解析,進行調用**Route::checkDomain()**域名解析處理 ~~~ if ('/' != $depr) { $url = str_replace($depr, '/', $url); } ~~~ url分隔符替換為"/" ~~~ if (empty($url)) { $url = '/'; } ~~~ $url為空時定位到根目錄 **下面包含多處返回結果。** >[info] 1 將$url映射返回到App::route() ~~~ if (isset(self::$map[$url])) { return self::parseUrl(self::$map[$url], $depr); } ~~~ 返回Route::$map中注冊的$url對應的映射信息。 如果存在調用**Route::parseUrl()**解析Url, **將解析結果[$type=>module,$method=>操作方法]返回給App::route()** **將解析結果調度類型為module,調度業務結構返回給App::route()** ~~~ $rules = self::$rules[REQUEST_METHOD]; if (!empty(self::$rules['*'])) { $rules = array_merge(self::$rules['*'], $rules); } ~~~ 獲取注冊的路由規則到$rules >[info] 2 返回url綁定結果 ~~~ $return = self::checkUrlBind($url, $rules); if ($return) { return $return; } ~~~ 調用**Route::checkUrlBind()**解析url 如果返回了解析結果 **將相關解析結果的調度類型$type,調度方法$method** **返回到App::route()中** `if (!empty($rules)) {}` 如果$rules 路由映射存在。 `foreach ($rules as $rule => $val) {}` 遍歷路由映射規則。 ~~~ $option = $val['option']; $pattern = $val['pattern']; ~~~ 獲取映射規則的選項$option與模式信息$pattern。 ~~~ if (!self::checkOption($option, $url)) { continue; } ~~~ 調用**Route::checkOption()**對$url中的參數進行檢查。 參數合法的解析解析本條規則, 否則跳出本條規則,解析下條規則 `if (!empty($val['routes'])) {}` 如果規則中存在路由映射,說明是分組路由。 對分組路由中的路由規則進行檢查 ~~~ if (0 !== strpos($url, $rule)) { continue; } ~~~ 檢查$url是否存在本地規則映射$rule中 查找失敗時解析下條映射規則。 `foreach ($val['routes'] as $key => $route) {}` 遍歷二級路由下的路由規則 ~~~ if (is_numeric($key)) { $key = array_shift($route); } ~~~ 返回數字形式$key `$url1 = substr($url, strlen($rule) + 1);` $url匹配截取 ~~~ if (is_array($route)) { $option1 = $route[1]; if (!self::checkOption($option1, $url)) { continue; } $pattern = array_merge($pattern, isset($route[2]) ? $route[2] : []); $route = $route[0]; $option = array_merge($option, $option1); } ~~~ 如果$route為數組,則進行參數檢查, 并解析模式,路由,選項參數到$pattern,$route,$option >[info] 3 返回分組路由解析結果 ~~~ $result = self::checkRule($key, $route, $url1, $pattern, $option); if (false !== $result) { return $result; } ~~~ 調用**Route::checkRule()**對分組路由規則進行檢查 并返回規則檢查結果 >[info] 4 返回簡單路由解析結果 ~~~ else { if (is_numeric($rule)) { $rule = array_shift($val); } $route = !empty($val['route']) ? $val['route'] : ''; $result = self::checkRule($rule, $route, $url, $pattern, $option); if (false !== $result) { return $result; } } ~~~ 調用**Route::checkRule()**對單條路由規則進行檢查 并返回規則檢查結果 >[info]5 返回false到App::run() `return false;` 如果映射規則失敗,返回false到App::run() ### 2 Route::checkDomain() 域名解析 `$rules = self::$domain;` 獲取注冊的域名規則 `if (!empty($rules)) {}` 如果有注冊的域名規則,則進行解析 ~~~ if (isset($rules[$_SERVER['HTTP_HOST']])) { $rule = $rules[$_SERVER['HTTP_HOST']]; } ~~~ 根據$_SERVER['HTTP_HOST']]獲取域名規則的規則 `$rootDomain = Config::get('url_domain_root');` 獲取失敗時,根據配置url_domain_root,獲取根域名 ~~~ if ($rootDomain) { $domain = explode('.', rtrim(stristr($_SERVER['HTTP_HOST'], $rootDomain, true), '.')); } else { $domain = explode('.', $_SERVER['HTTP_HOST'], -2); } ~~~ 以"."分割域名信息為數組。 `if (!empty($domain)) {}` 獲取根域名成功,繼續解析 ~~~ $subDomain = implode('.', $domain); self::$subDomain = $subDomain; ~~~ 獲取子域名字符串 `$domain2 = array_pop($domain);` 2級域名字符串 ~~~ if ($domain) { $domain3 = array_pop($domain); } ~~~ 3級域名字符串 ~~~ if ($subDomain && isset($rules[$subDomain])) { $rule = $rules[$subDomain]; } ~~~ 子域名對應規則 ~~~ elseif (isset($rules['*.' . $domain2]) && !empty($domain3)) { $rule = $rules['*.' . $domain2]; $panDomain = $domain3; } ~~~ 泛三級域名獲取。 ~~~ elseif (isset($rules['*']) && !empty($domain2)) { if ('www' != $domain2) { $rule = $rules['*']; $panDomain = $domain2; } } ~~~ 泛二級域名獲取 `if (!empty($rule)) {}` 獲取域名規則成功時 ~~~ if ($rule instanceof \Closure) { $reflect = new \ReflectionFunction($rule); self::$bind = $reflect->invokeArgs([]); return; } ~~~ 域名規則閉包檢查,并調用 ~~~ if (strpos($rule, '?')) { $array = parse_url($rule); $result = $array['path']; parse_str($array['query'], $params); if (isset($panDomain)) { $pos = array_search('*', $params); if (false !== $pos) { // 泛域名作為參數 $params[$pos] = $panDomain; } } $_GET = array_merge($_GET, $params); } ~~~ 域名規則中包含?字符,合并生成$_GET參數 并將規則的path解析結果保存到$result ~~~ if (0 === strpos($result, '\\')) { self::$bind = ['type' => 'namespace', 'namespace' => $result]; } ~~~ `\\` 綁定類型設置為命名空間。 ~~~ elseif (0 === strpos($result, '@')) { self::$bind = ['type' => 'class', 'class' => substr($result, 1)]; } ~~~ `@`綁定類型設置為類。 ~~~ elseif (0 === strpos($result, '[')) { self::$bind = ['type' => 'group', 'group' => substr($result, 1, -1)]; } ~~~ `[` 綁定類型設置為規則組。 ~~~ else { self::$bind = ['type' => 'module', 'module' => $result]; } ~~~ 其他綁定類型設置為module >[info] Route::checkDomain()根據self::domain解析域名到 > self::$subDomain 子域名字符串 > self::$bind 綁定類型在Route::checkUrlBind()設置不同調度類型。 **域名解析完成后返回Route::check()** ### 3 Route::parseUrl() Url映射解析 `public static function parseUrl($url, $depr = '/')` > $url:待解析$url > $depr:解析$url時使用的分隔符 ~~~ if (isset(self::$bind['module'])) { $url = self::$bind['module'] . '/' . $url; } ~~~ 綁定模塊時將$url添加到module后面組成module/$url ~~~ if ('/' != $depr) { $url = str_replace($depr, '/', $url); } ~~~ 再次替換分隔符, `$result = self::parseRoute($url, true);` 調用**Route::parseRoute()** 進入**[模塊/控制器/操作?]參數1=值1&參數2=值2...**路由解析 ~~~ if (!empty($result['var'])) { $_GET = array_merge($result['var'], $_GET); } ~~~ 將解析得到的$var合并到$_GET中 ` return ['type' => 'module', 'module' => $result['route']];` 返回調度類型$type為module,應用業務$module為$result['route'] >[info] Route::parseUrl()將url解析為模塊/控制器/操作, > 并合并參數到$_GET中。 **并將調度類型,應用業務的結果返回到Route::check()** ### 4 Route::checkUrlBind() Url綁定類型解析 `private static function checkUrlBind(&$url, &$rules)` > $url:待解析$url引用 > $rules:待解析$rules規則引用 `if (!empty(self::$bind['type'])) {}` 檢查是否存在綁定類型 這里的self::$bind在域名解析**Route::checkDomain()**生成。 `APP_DEBUG && Log::record('[ BIND ] ' . var_export(self::$bind, true), 'info');` 記錄綁定信息。 `switch (self::$bind['type']) {}` 根據綁定類型進行處理 ~~~ case 'class': $array = explode('/', $url, 2); if (!empty($array[1])) { self::parseUrlParams($array[1]); } return ['type' => 'method', 'method' => [self::$bind['class'], $array[0] ?: Config::get('default_action')], 'params' => []]; ~~~ **class類型綁定** 解析url參數,返回調度類型$type為method,調度業務$method。 這里的method對應App::run()中的調度類型。 ~~~ case 'namespace': $array = explode('/', $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])) { self::parseUrlParams($array[2]); } return ['type' => 'method', 'method' => [self::$bind['namespace'] . '\\' . $class, $method], 'params' => []]; ~~~ **namespace類型綁定** 解析url參數,返回調度類型型$type為method,調度業務$method 這里的method對應App::run()中的調度類型 ~~~ case 'module': $url = self::$bind['module'] . '/' . $url; break; ~~~ **module類型綁定** 將self::$bind['module]合并到$url ~~~ case 'group': $key = self::$bind['group']; if (array_key_exists($key, $rules)) { $rules = [$key => $rules[self::$bind['group']]]; } ~~~ **group類型綁定** 將路由規則合并到$rule。 ### 5 Route::checkOption() 規則中參數有效性檢查 ~~~ if ((isset($option['method']) && false === stripos($option['method'], REQUEST_METHOD)) || (isset($option['ext']) && false === stripos($option['ext'], __EXT__)) // 偽靜態后綴檢測 || (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名檢測 || (!empty($option['https']) && !self::isSsl()) // https檢測 || (!empty($option['before_behavior']) && false === Hook::exec($option['before_behavior'], $url)) // 行為檢測 || (!empty($option['callback']) && is_callable($option['callback']) && false === call_user_func($option['callback'])) // 自定義檢測 ) ~~~ >[info] method選項參數 > ext 選項參數 > domain 選項參數 > https 選項參數進行isSsl()檢測 > before_behavior 選項參數檢查 并調用Hook::exec()調度行為 > callback 選項參數檢查 調用callback回調 ### 6 Route::checkRule() 路由規則檢查 `private static function checkRule($rule, $route, $url, $pattern, $option)` > $rule:待解析規則$rule > $route:待解析路由$route > $url:待解析$url > $pattern:待解析模式參數$pattern > $option:待解析選項參數$option ~~~ if (isset($pattern['__url__']) && !preg_match('/^' . $pattern['__url__'] . '/', $url)) { return false; } ~~~ `__url__`模式匹配檢查 ~~~ if ($depr = Config::get('url_params_depr')) { $url = str_replace($depr, '/', $url); $rule = str_replace($depr, '/', $rule); } ~~~ $url中參數分隔符替換為配置分隔符 ~~~ $len1 = substr_count($url, '/'); $len2 = substr_count($rule, '/'); ~~~ 獲取$url,$rule中"/"符號個數 `if ($len1 >= $len2 || strpos($rule, '[')) {}` $rule是$url一部分,或者$rule中包含"["時才進行進一步解析 ~~~ if ('$' == substr($rule, -1, 1)) { if ($len1 != $len2) { return false; } else { $rule = substr($rule, 0, -1); } } ~~~ $rule 以'$'結尾時 完整匹配 并獲取除"$"外的$rule ~~~ $pattern = array_merge(self::$pattern, $pattern); ~~~ 合并模式參數$pattern到Route::$pattern `if (false !== $match = self::match($url, $rule, $pattern)){}` 調用Route::match()進行$url與$rule匹配檢查。 如果參數檢測成功時 ~~~ if (!empty($option['after_behavior'])) { Hook::exec($option['after_behavior'], $route); } ~~~ 如果選項$option中包含after_behavior 運行選項中的after_behavior對應的標簽信息。 ~~~ if ($route instanceof \Closure) { return ['type' => 'function', 'function' => $route, 'params' => $match]; } ~~~ 如果對應的$route是個閉包, 返回調度類型$type為function,調度業務$function `return self::parseRule($rule, $route, $url);` $option選項參數中沒有after_behavior并且$route不是閉包時 調用**Route::parseRule()**解析路由規則 ### 7 Route::match() Url和規則路由匹配 `private static function match($url, $rule, $pattern)` > $url:待匹配$url > $rule:待匹配$rule > $pattern:待匹配$rule中的模式參數$pattern ~~~ $m1 = explode('/', $url); $m2 = explode('/', $rule); ~~~ 使用"/"分割$url,$rule ~~~ if (0 === strpos($val, '[:')) { $val = substr($val, 1, -1); } ~~~ $rule第一個字符串為"[:"時,可選參數。 `if (0 === strpos($val, ':')) {}` $rule第一個字符串為":"時,url變量。 `$name = substr($val, 1);` 獲取變量名稱$name ~~~ if (isset($m1[$key]) && isset($pattern[$name]) && !preg_match('/^' . $pattern[$name] . '$/', $m1[$key])) { return false; } ~~~ 對$url,$rule,$pattern中的$name進行匹配檢查 `$var[$name] = $m1[$key];` 獲取$url參數到$val ~~~ elseif (0 !== strcasecmp($val, $m1[$key])) { return false; } ~~~ 其他情況,完全對比 `return $var;` 返回匹配成功的參數信息 ### 8 Route::parseRule() 規則解析 `private static function parseRule($rule, $route, $pathinfo)` > $rule:待解析規則 > $route:待解析路由 > $pathinfo:待解析$pathinfo ~~~ $paths = explode('/', $pathinfo); ~~~ 分隔$pathinfo參數為數組 `$url = is_array($route) ? $route[0] : $route;` 獲取$route中的路由$url信息 `$rule = explode('/', $rule);` 分隔$rule規則信息 ~~~ foreach ($rule as $item) { $fun = ''; if (0 === strpos($item, '[:')) { $item = substr($item, 1, -1); } if (0 === strpos($item, ':')) { $var = substr($item, 1); $matches[$var] = array_shift($paths); } else { array_shift($paths); } } ~~~ 對$rule規則的變量名進行過濾處理 ~~~ foreach ($matches as $key => $val) { if (false !== strpos($url, ':' . $key)) { $url = str_replace(':' . $key, $val, $url); unset($matches[$key]); } } ~~~ 替換$url中的參數 if (0 === strpos($url, '/') || 0 === strpos($url, 'http')) { $result = ['type' => 'redirect', 'url' => $url, 'status' => (is_array($route) && isset($route[1])) ? $route[1] : 301]; } **"/"或者"http"開頭的$url,解析為redirect調度類型** elseif (0 === strpos($url, '\\')) { $result = ['type' => 'method', 'method' => is_array($route) ? [$url, $route[1]] : $url, 'params' => $matches]; } **"\\"開頭的$url,解析為method調度類型** ~~~ elseif (0 === strpos($url, '@')) { $result = ['type' => 'controller', 'controller' => substr($url, 1), 'params' => $matches]; } ~~~ **"@"開頭的$url,解析為controller調度類型** else {} 其他情況手動解析$url `$result = self::parseRoute($url);` 調用**Route::parseRoute()**解析$url `$var = array_merge($matches, $result['var']);` 合并解析結果的$result['var']與參數信息$matches到$var `self::parseUrlParams(implode('/', $paths), $var);` 調用Route::parseUrlParams()解析$url中的參數 `$result = ['type' => 'module', 'module' => $result['route']];` 解析結果為module調度類型 ~~~ Config::set('url_controller_convert', false); Config::set('url_action_convert', false); ~~~ 關閉控制器和操作的自動轉換 ` return $result;` 返回包含調度類型$type,調度業務$app的$result。 ### 9 Route::parseRoute() 路由規則地址解析 ~~~ if (false !== strpos($url, '?')) { $info = parse_url($url); $path = explode('/', $info['path'], 4); parse_str($info['query'], $var); } elseif (strpos($url, '/')) { $path = explode('/', $url, 4); } elseif (false !== strpos($url, '=')) { parse_str($url, $var); } else { $path = [$url]; } ~~~ >[info] [模塊/控制器/操作?]參數1=值1&參數2=值2... 路由格式解析 保存信息到$info,$path,$var中。 ~~~ if (!empty($path[3])) { preg_replace_callback('/([^\/]+)\/([^\/]+)/', function ($match) use (&$var) { $var[strtolower($match[1])] = strip_tags($match[2]); }, array_pop($path)); } ~~~ 如果存在$path, 首先解析模塊/控制器/操作后面的$path[3]參數。 ~~~ if ($reverse) { $module = APP_MULTI_MODULE ? array_shift($path) : null; $controller = !empty($path) ? array_shift($path) : null; $action = !empty($path) ? array_shift($path) : null; } ~~~ 如果$reverse為true,則順序解析為模塊,控制器,操作 ~~~ $action = array_pop($path); $controller = !empty($path) ? array_pop($path) : null; $module = APP_MULTI_MODULE && !empty($path) ? array_pop($path) : null; ~~~ 如果$reverse為false,則倒序解析為模塊,控制器,操作 ~~~ if ('[rest]' == $action) { $action = REQUEST_METHOD; } ~~~ rest操作解析 `$route = [$module, $controller, $action];` 合并模塊/控制器/操作到$route `return ['route' => $route, 'var' => $var];` 返回解析得到的模塊/控制器/路由$route和參數$var ### 10 Route::parseUrlParams() 解析Url參數 `private static function parseUrlParams($url, $var)` > $url:待解析參數的$url > $var:待解析參數 ~~~ if ($url) { preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) { $var[strtolower($match[1])] = strip_tags($match[2]); }, $url); } ~~~ 匹配$url中的參數到$var `$_GET = array_merge($var, $_GET);` 合并參數$var到$_GET ## 5 路由規則注冊Route.php ### Route::map() 注冊$url到路由$route的映射規則 `public static function map($map = '', $route = '')` ### Route::pattern() 注冊$url參數變量規則 `public static function pattern($name = '', $rule = '')` ### Route::domain() 注冊$url域名解析規則 `public static function domain($domain = '', $rule = '')` ### Route::bind() 路由綁定和獲取 `public static function bind($type, $bind = '')` ### Route::set() 上述調用的屬性設置與獲取 `private static function setting($var, $name = '', $value = '')` ## 6 Url生成 ## 7 框架路由示例
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看