首頁 > php框架 > ThinkPHP > ThinkPHP偵測URL路由深度解析

ThinkPHP偵測URL路由深度解析

咔咔
發布: 2020-12-01 13:41:01
原創
2119 人瀏覽過

前言

#由於文章篇幅的原因,執行在新開一篇文章進行寫。

在上一篇中跟大家講解了以下內容。

  • 路由初識化簡單分析
  • 透過定義路由再談門面
  • #路由定義rule方法中的$this->group到底執行了什麼
  • 路由規則預處理
  • 解析產生路由標識的快捷存取

但在路由這塊還有很多的內容要來講解,接下來就會針對以下內容進行解析。

  • 路由配置(就是在route檔案中的return中)
  • #dispatch初步認識

ThinkPHP偵測URL路由深度解析# #route-check 偵測URL路由

。 。 。 。 。 。 。 。 。 。 。 。 。 接下來就一個一個進行詳解。 同樣為大家放一個關於路由的執行圖,供大家參考。

###路由的執行流程###################一、dispatch初認識以及route-check 偵測URL路由##### ###########這塊的內容是在執行應用程式裡邊,接下來喀喀帶大家簡單的認識。 ###

本節沒有原始碼的解釋,只是為了後文坐鋪墊使用的,所以很有必要知道dispatch是怎麼一個回事。

下圖就是執行完路由初始化之後回傳上層繼續執行的流程。

然後就會執行到路由偵測這裡。

ThinkPHP偵測URL路由深度解析
dispatch初始執行位置

路由測試使用如下圖

ThinkPHP偵測URL路由深度解析
路由測試使用案例

然後我們可以對這個調度資訊進行列印

ThinkPHP偵測URL路由深度解析
列印資料
ThinkPHP偵測URL路由深度解析
列印結果

在上圖已經印了關於dispatch的相關的值

接下來就會針對routeCheck方法進行簡單的預覽

ThinkPHP偵測URL路由深度解析
routeCheck

在上圖方法中只要明確在這一步驟會處理緩存,並且傳回一個Dispatch物件即可。

這塊的源碼大家可以簡單的看一下即可,不是很重要。

route-check 偵測URL路由

但這塊的內容還是需要簡單的去看一下的。

在看之前需要先明確一下傳入的兩個參數分別是什麼。

參數一:路由規則 參數二:偵測是否配置了強制路由

ThinkPHP偵測URL路由深度解析
傳回一個dispatch物件

知道了參數的意義後就需要去到check這個方法中一探究竟了。

ThinkPHP偵測URL路由深度解析
偵測url路由

在這個方法中關於自動偵測網域路由我們來列印一下資料是什麼樣的。

其實這個回傳的結果就是跟之前資源路由掛載的方式是一樣的,

ThinkPHP偵測URL路由深度解析
#列印結果
##然後會通過pathinfo分隔符號: 把url中的/ 改為|

並且會在設定檔取得路由是否完全符合

最終執行使用預設路由解析

這裡邊的細節就不去深度解析了,關於路由這塊的細節是在是太多了,如果一個一個去針對細節,那是需要耗費大量的時間的。

所以這塊的內容就到這裡了,只需要知道執行了什麼,並且最終返回的是什麼即可。

二、request類別是如何找到的

在上一節中

$result = $ domain->check($this->request, $url, $completeMatch);會執行這一塊的內容。

這裡不關心這個方法執行了什麼。

而是需要關心這個$this->request是如果找到並且執行的。

首先可以看到的是在Route類別中是存在request這個屬性的。

ThinkPHP偵測URL路由深度解析
請求物件的屬性

接著來到Route的建構函數,在這裡你會發現新天地。

這裡使用了ArrayAccess像數組一樣存取對象,但是$app中不存在request屬性,所以就會去執行容器類別中的__get魔術方法,在__get方法中調用的是容器中的make方法,第一個參數為request,最終會傳回request的實例。

ThinkPHP偵測URL路由深度解析
建構子

這裡的$app其實是透過依賴注入進來的App實例。

看了這麼多的原始碼肯定知道App類別是繼承Container類別的也就是容器類別。

在容器類別中得最下邊會有幾個魔術方法。

這裡只需要關注__get方法即可。

ThinkPHP偵測URL路由深度解析
魔術方法

__get方法會在存取不存在的屬性時會執行的函數。

也就說最終會執行到make方法。

ThinkPHP偵測URL路由深度解析
容器類別中的make方法

這個方法會通過一系列的操作,最後傳回一個Request的實例。

並且把這個實例存放到容器裡邊,下次使用時直接取得即可。

關於容器類別中的make方法是容器類別中特別重要的方法,也是靈魂方法。

全框架的實例都是透過容器回傳的,所以說這個方法的重要性就不用咔咔在多說了。

咔咔之前對容器進行特別深入的理解,並且用文章的形式呈現給了大家。

三、偵測網域路由

#先給大家把流程圖畫出來,然後依照流程跟著這樣咔咔的節奏即可。

ThinkPHP偵測URL路由深度解析
路由網域偵測流程圖

首先要確認的一件事情就是偵測網域路由是在執行應用程式中執行的。

上層執行流程就是在入口檔案哪裡。

ThinkPHP偵測URL路由深度解析
執行應用程式

首先程式碼會執行到routeCheck這個方法裡邊,那就先看這個檔案。

先看註釋,對這個方法的解釋就是URL路由偵測。

在這個方法裡邊先是會對路由快取進行偵測,這塊內容就是關於Cache的。

在這個方法裡邊最重要的就是路由偵測 回傳一個Dispatch物件就是這個方法。

ThinkPHP偵測URL路由深度解析
URL路由偵測

那麼接下裡面就是看這個方法。

首先要明確的就是傳進去的兩個參數都是什麼。

  • $path : string(4) "blog"
  • #$must : bool(false)
ThinkPHP偵測URL路由深度解析
#路由偵測

在偵測URL路由中會做以下幾件事情。

  • pathinfo分隔符號: 把url中的/ 改為|
  • 路由是否完全符合
  • 偵測網域路由
  • 預設路由解析

#接下來就只需要對偵測網域名稱路由流程進行深入解析。

關於前兩個執行只是一些字串的處理,看看就行,知道最終回傳什麼即可。

ThinkPHP偵測URL路由深度解析
偵測URL路由

同樣在偵測網域路由的執行上明確三個參數的意義。

  • $this->request : 透過容器類別的__get魔術方法,執行容器類別的make方法,最終返回request的實例對象,這列不會的去看第六節的文章
  • $url : string(4) "blog"
  • $completeMatch : 路由是否完全匹配

來到$result = $domain->check($this->request, $url, $completeMatch);這裡,也就是本節的重點了。

在這個方法裡邊會執行以下幾個流程,會針對重要的執行流程進行深度解析。

  • 偵測路由別名: checkRouteAlias
  • #偵測URL綁定:checkUrlBind
  • 判斷路由參數
  • 新增網域中間件
  • 偵測分組路由:parent::check
ThinkPHP偵測URL路由深度解析
# #偵測網域路由

偵測路由別名: checkRouteAlias

    #參數解釋
  • ##$request : request類別的實例
  • $url : 傳過來的blog

#在這個方法裡邊存在兩個需要明確的知識點
  • strpos : 尋找在字串中第一次出現的位置
  • strstr : strstr傳回一個指針,指向string2在string1中首次出現的位置,strstr( "Helloworld!","world");?>\n輸出:\nworld!
  • #首先會對URL位址處理:回傳blog
  • 取得別名路由定義 NULL
  • 以資源路由blog為例傳回false
ThinkPHP偵測URL路由深度解析
偵測路由別名

在偵測路由別名中存在一個方法需要去在看一下

參數就是上圖傳入的blog###
ThinkPHP偵測URL路由深度解析
取得別名路由定義

來到這個方法,首先要明確的事情就是此方法在類別thinkphp/library/think/Route.php

並且此類使用了think\route下的所有類別

這個方法就會把從檢測路由過來的blog然後會在Route類別中的alias屬性裡邊進行獲取,如果不存在則會傳回NULL

這個別名的使用會在下文中提到

ThinkPHP偵測URL路由深度解析
以取得別名路由定義

來到偵測別名路由的最後return $item ? $item->check($request, $url) : false;也就是這行程式碼,從上圖就可以知道,這個item就是NULL

並且最終將這個NULL給回回去。

偵測URL綁定:checkUrlBind

參數說明

  • $request : request類別的實例
  • #$url : 傳過來的blog

在這個方法中只對下圖喀喀一聲出來的地方進行詳解。

ThinkPHP偵測URL路由深度解析
偵測URL綁定

來到方法getBind讀取路由綁定,可以看到咔咔已經將傳入的參數印出來了。

本方法是在thinkphp/library/think/route/Domain.php這個類別裡邊,還記得在設定路由規則的$This->group就是使用的這個類,不知道的可以去看路由文章的第一節。

同時在這個方法中會進行一次subDomain目前子網域的取得。

在這個方法最後會回到www,主要看一下圈出來的第一個部分。

透過request類別中的host方法來取得目前域名,然後進行分割。

傳回資料:array(1) { [0] =>\n string(3) "www"\n}

給子網域賦值:$this->subDomain

返回最終結果返回子網域: www

ThinkPHP偵測URL路由深度解析
取得目前子網域

接著就會回到上層,在上層進行判斷獲取的目前子網域WWW。

有些是所有的判斷處理,第一個判斷肯定是不會成立的,因為只回傳了www,並沒有.

下邊的判斷是根據路由綁定進行的判斷,這裡只需要知道最總是會回傳NULL就可以了。

ThinkPHP偵測URL路由深度解析
進行的判斷

知道了在底層返回了NULL,所以這裡的判斷同樣也不會成立,所以最終給上層返回的結果就是false。

ThinkPHP偵測URL路由深度解析
偵測URL綁定

判斷路由參數

根據上圖執行流程最終還是會回到thinkphp/library/think/route/Domain.php這個方法check偵測網域路由。

然後開始進行判斷路由參數。

沒有路由參數跳過不執行。

有路由參數:執行方法setRouteVars :設定路由變數  這個參數是在框架版本5.1.5以上才可以使用,由於喀喀爾使用的版本有點低,就不對其詳解了。

ThinkPHP偵測URL路由深度解析
偵測網域名稱路由
ThinkPHP偵測URL路由深度解析
文件

新增網域中間件

關於中間件這裡也不對其進行解釋,因為後期會新開一篇文章來詳解,本文還是以路由為重點哈!

偵測分組路由

接著就會來到偵測網域路由的最後一個流程,執行程式碼return parent::check($request, $url , $completeMatch);

會跳到類別檔:thinkphp/library/think/route/RuleGroup.php,因為Domain類別是繼承RuleGroup這個類別的。

參數說明

  • $request : request類別的實例
  • $url : 傳過來的 blog
  • ##$completeMatch :路由是否完全符合
在這個方法中喀喀爾只會對這裡的其中的一個流程進行詳解,也就是合併分組參數。

因為這個方法也是貫穿執行流程的一條主線,其餘的都是方法都是在進行偵測,判斷。

ThinkPHP偵測URL路由深度解析合併分組參數

#四、總結

關於路由用了倆篇文章還沒結束,看了這麼長時間的源碼也就是路由這塊是最複雜並且最難理解的。

其中的類別是一環套一環,路由先暫時了解到這裡,後期在閱讀其它源碼時在進行其它內容補充。

在路由這篇文章中主要執行的流程圖大家一定要仔細看。 ThinkPHP偵測URL路由深度解析
執行流程圖

在就是透過在註冊路由規則時的group這個屬性最終返回的是Domain類,這裡的內容一定要清晰。

主要知道在路由中網域的設定流程,網域是在何時進行設定的。

路由檔案中的回傳陣列和在匯入路由檔案流程要有清晰的思路。

再就是回顧之前學習的ArrayAccess,像存取陣列一樣存取物件。

容器中的魔術方法__get方法,在這個魔術方法中存在make方法,主要用來傳回一個類別的實例,並且存放到容器中。

###關於路由的面向暫時就說到這裡的,預計在有一篇就會把路由寫完了。 ###

堅持學習、堅持寫博、堅持分享是咔咔從業以來一直所秉持的信念。希望在諾大互聯網中咔咔的文章能帶給你一絲幫助。我是咔咔,下期見。

#

以上是ThinkPHP偵測URL路由深度解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板