<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                :-: **1 路由解析** >[danger] 在App的run()方法初始化后,開始進行請求路由解析 > > 請求解析的過程就是講url根據注冊的路由分派到對應的應用層業務邏輯 > > 請求解析的實現由/library/think/Route實現 * * * * * :-: **2 路由解析入口源碼分析** * * * * * ~~~ //App run()方法 // 初始化應用 $this->initialize(); if ($this->bind) { // 模塊/控制器綁定 $this->route->bind($this->bind); } elseif ($this->config('app.auto_bind_module')) { // 入口自動綁定 $name = pathinfo($this->request->baseFile(), PATHINFO_FILENAME); if ($name && 'index' != $name && is_dir($this->appPath . $name)) { $this->route->bind($name); } } ~~~ >[danger] 首先檢查App的屬性bind,是否綁定到特定模塊/控制器 > 如果App的屬性bind沒有設置,則讀取配置的`app.auto_bind_module`。 > 如果設置了自動綁定模塊,則將入口文件名綁定為模塊名稱。 > 比如設置app的auto_bind_module為ture。則訪問admin.php入口文件。 > 那么默認的模塊就是admin模塊 ~~~ // 監聽app_dispatch $this->hook->listen('app_dispatch'); ~~~ 調用app_dispatch的回調函數 ~~~ $dispatch = $this->dispatch; if (empty($dispatch)) { // 進行URL路由檢測 $this->route->lazy($this->config('app.url_lazy_route')); $dispatch = $this->routeCheck(); } $this->request->dispatch($dispatch); ~~~ >[danger] 獲取應用的調度信息。這里的routeCheck()是路由解析的入口 > 然后將解析的調度信息保存到全局Request對象中。 ~~~ if ($this->debug) { $this->log('[ ROUTE ] ' . var_export($this->request->routeInfo(), true)); $this->log('[ HEADER ] ' . var_export($this->request->header(), true)); $this->log('[ PARAM ] ' . var_export($this->request->param(), true)); } ~~~ >[danger] 調試模式下,保存路由的請求信息到日志文件中 ~~~ // 監聽app_begin $this->hook->listen('app_begin'); ~~~ >[danger] 調用app_begin的回調函數 ~~~ $this->request->cache( $this->config('app.request_cache'), $this->config('app.request_cache_expire'), $this->config('app.request_cache_except') ); ~~~ >[danger]檢查否開啟了請求緩存, >如果設置了緩存,則嘗試讀取緩存結果 ~~~ // 執行調度 $data = $dispatch->run(); ~~~ >[danger]這里執行調度。也就是執行請求分派到的業務邏輯, >通常是模塊/控制器中的特定方法。也可以是其他形式的業務邏輯 >比如 閉包函數,或者直接返回模板等。 ~~~ $this->middlewareDispatcher->add(function (Request $request, $next) use ($data) { // 輸出數據到客戶端 if ($data instanceof Response) { $response = $data; } elseif (!is_null($data)) { // 默認自動識別響應輸出類型 $isAjax = $request->isAjax(); $type = $isAjax ? $this->config('app.default_ajax_return') : $this->config('app.default_return_type'); $response = Response::create($data, $type); } else { $response = Response::create(); } return $response; }); $response = $this->middlewareDispatcher->dispatch($this->request); ~~~ >[danger] 這里是think5.1準備添加的中間件功能。 ~~~ $this->hook->listen('app_end', $response); return $response; ~~~ >[danger] 調度執行完后,調用app_end的回調函數 > 最后run()方法返回創建的響應對象Response >然后在入口文件index.php中調用Response的send()將結果輸出到客戶端 `Container::get('app')->run()->send();` :-: **3 路由注冊過程源碼分析** >[danger] 由上面的分析可知 路由解析的入口是App的routeCheck() > 下面開始分析App的routeCheck()是如何解析請求Request得到調度信息的 ~~~ //App routeCheck() $path = $this->request->path(); $depr = $this->config('app.pathinfo_depr'); ~~~ >[danger]調用Request的path()方法獲取當前請求的pathinfo信息 >然后讀取app.pathinfo_depr獲取pathinfo的分隔符 >這里的path就是請求的url`index/blog/index`。pathifo_depr也就是url分隔符`/` ~~~ $files = scandir($this->routePath); foreach ($files as $file) { if (strpos($file, '.php')) { $filename = $this->routePath . $file; // 導入路由配置 $rules = include $filename; if (is_array($rules)) { $this->route->import($rules); } } } ~~~ >[danger]這里遍歷路由目錄/route/中的所有文件。將其中的路由規則導入 >也就是將配置的路由信息加載到框架中。 >然后根據注冊的路由信息匹配請求url ~~~ if ($this->config('app.route_annotation')) { // 自動生成路由定義 if ($this->debug) { $this->build->buildRoute($this->config('app.controller_suffix')); } $filename = $this->runtimePath . 'build_route.php'; if (is_file($filename)) { include $filename; } } ~~~ >[danger]這里檢查是否配置了注釋自動生成路由 >如果開啟了注釋路由,則調用Build的buildRoute()解析注釋為路由 >然后將解析后的路由文件build_route.php加載到框架中 ~~~ $must = !is_null($this->routeMust) ? $this->routeMust : $this->config('app.url_route_must'); return $this->route->check($path, $depr, $must, $this->config('app.route_complete_match')); ~~~ >[danger]檢查配置url_route_must是否開啟。 >如果開啟,則每個請求必須配置路由,否則默認按照模塊/控制器/操作解析 >最后調用Route的check()方法在路由中匹配url。返回匹配后的調度信息Dispatch :-: **4 url與路由匹配過程源碼分析** >[danger]在Route的check()開始在注冊的路由中匹配url ~~~ $domain = $this->checkDomain(); ~~~ >[danger]首先檢查是否注冊了請求的域名路由信息。 >注冊的域名路由信息保存在Route的domains屬性中 >如果注冊了域名路由信息,則返回對應的域名路由信息 ~~~ $url = str_replace($depr, '|', $url); ~~~ >[danger] 將url的分隔符替換為| ~~~ $result = $domain->check($this->request, $url, $depr, $completeMatch); ~~~ >[danger] 調用域名路由的Check()方法,匹配請求url >[danger]這里的check()方法在/route/Domain.php文件中 >主要進行路由的別名和url綁定檢查 checkouteAlias() checkUrlBind() >路由的別名和url綁定檢查由Route的getAlias()和getBind()實現 >在getAlias()和getBind()中主要讀取了Route的alias和bind屬性 >檢查是否包含了當前url和域名對應的路由信息 >[danger]最后調用Domain的父對象組路由RuleGroup的check()進行路由檢查 >在RuleGroup()首先檢查跨域請求checkCrossDomain() >然后檢查路由規則的option參數是否有效checkOption() >然后檢查分組路由的url是否匹配checkUrl() ~~~ if ($this->rule) { if ($this->rule instanceof Response) { return new ResponseDispatch($this->rule); } $this->parseGroupRule($this->rule); } ~~~ >[danger]如果上述條件都符合,那么當前的路由規則就是請求url對應的路由 >然后讀取路由中注冊的調度信息rule >如果注冊的路由調度信息rule是調度對象,則直接返回調度對象 >否則調用分組路由解析。也就是生成分組的多條路由調度信息rule ~~~ // 分組匹配后執行的行為 $this->afterMatchGroup($request); // 獲取當前路由規則 $method = strtolower($request->method()); $rules = $this->getMethodRules($method); if ($this->parent) { // 合并分組參數 $this->mergeGroupOptions(); } if (isset($this->option['complete_match'])) { $completeMatch = $this->option['complete_match']; } if (!empty($this->option['merge_rule_regex'])) { // 合并路由正則規則進行路由匹配檢查 $result = $this->checkMergeRuleRegex($request, $rules, $url, $depr, $completeMatch); if (false !== $result) { return $result; } } // 檢查分組路由 foreach ($rules as $key => $item) { $result = $item->check($request, $url, $depr, $completeMatch); if (false !== $result) { return $result; } } ~~~ >[danger]接下來在生成的分組路由的多條調度信息中匹配請求的url >得到匹配的結果$result。 ~~~ if ($this->auto) { // 自動解析URL地址 $result = new UrlDispatch($this->auto . '/' . $url, ['depr' => $depr, 'auto_search' => false]); } elseif ($this->miss && in_array($this->miss->getMethod(), ['*', $method])) { // 未匹配所有路由的路由規則處理 $result = $this->parseRule($request, '', $this->miss->getRoute(), $url, $this->miss->getOption()); } else { $result = false; } return $result; ~~~ >[danger]如果在分組路由中沒有找到url對應的路由規則 >則在auto和miss分組路由中嘗試匹配。 >最后返回匹配的結果 >也就是生成的調度信息 ~~~ if (false === $result && !empty($this->cross)) { // 檢測跨域路由 $result = $this->cross->check($this->request, $url, $depr, $completeMatch); } ~~~ >[danger]這里返回到Route的路由檢查check()方法中 >如果沒有匹配到當前url。則檢查是否設置跨域路由 >嘗試檢查跨域路由 ~~~ if (false !== $result) { // 路由匹配 return $result; } elseif ($must) { // 強制路由不匹配則拋出異常 throw new RouteNotFoundException(); } ~~~ >[danger]如果得到匹配的路由調度信息則返回$result >否則檢查是否設置強制路由, >開啟強制路由時,匹配路由失敗則跑出路由不匹配異常 ~~~ return new UrlDispatch($url, ['depr' => $depr, 'auto_search' => $this->config->get('app.controller_auto_search')]); ~~~ >[danger]如果沒有開啟強制路由,則返回url到模塊/控制器/操作的url調度對象 >得到調度對象,返回App的run()中開始記錄調度信息到request >然后調用調度對象Dispatch的run()方法 :-: **5 調度對象的執行** >[danger]調度對象Dispatch在think中由/route/dispatch/目錄中實現 >主要包括繼承了基礎調度對象dispath的閉包回調,控制器,模塊,跳轉,url,視圖等調度對象 >在url調度對象中調用了模塊調度對象,在模塊調度對象中最終執行了業務邏輯控制器的操作。 >操作的執行結果返回到App的run()方法中保存到$data >然后創建對應的響應對象Response >響應對象在/response/中實現為json,jsonp,jump,redirect,view,xml等響應對象 >其中的view也就是通常的模板響應對象
                  <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>

                              哎呀哎呀视频在线观看