一、解析匹配到的規(guī)則路由-路由地址動(dòng)態(tài)處理
在上文執(zhí)行完的過程中會(huì)發(fā)生幾種情況,咔咔這里給大家整理一下,由于寫的比較多怕有時(shí)候看的時(shí)候就混淆了。
第一種情況
沒有任何路由參數(shù)和路由規(guī)則,就單純的路由地址。
在這里打印一下檢測(cè)URL和規(guī)則路由是否匹配的返回結(jié)果,以下的幾種情況都使用的同一個(gè)地方打印,就不在寫第二次了。
也就是當(dāng)路由地址為純路由地址時(shí)返回的是一個(gè)空數(shù)組。
第二種情況
設(shè)置有路由參數(shù)并且是必選參數(shù),會(huì)返回參數(shù)和值并且是數(shù)組形式。
第三種情況
設(shè)置有資源路由參數(shù)并且是必選參數(shù),會(huì)返回參數(shù)和值并且是數(shù)組形式,如果沒有參數(shù)則返回false。
接下來在進(jìn)入到本節(jié)的正題,為什么要做對(duì)以上的三種情況做出聲明,請(qǐng)看下圖咔咔圈出來的地方。
以上三種情況的打印結(jié)果就是$match
這個(gè)的值,所以當(dāng)$match
值為false時(shí)整個(gè)流程會(huì)直接返回false。
不會(huì)在去執(zhí)行解析匹配到的規(guī)則路由這一步驟。
在這里會(huì)執(zhí)行幾個(gè)動(dòng)作,分別為
-
檢查OPTIONS請(qǐng)求 -
檢查前置行為 -
解析匹配到的規(guī)則路由
而且我們要學(xué)習(xí)的就是解析匹配到的規(guī)則路由這個(gè)里邊的內(nèi)容。
使用以下路由作為案例進(jìn)行執(zhí)行流程。
解析匹配到的規(guī)則路由
參數(shù)說明
-
$request : object(thinkRequest) 請(qǐng)求類
-
$this->rule : string(13) "hello/<name?>" 路由規(guī)則 -
$this->route : string(17) "index/index/hello" 路由地址 -
$url : string(5) "hello" 請(qǐng)求地址 -
$option : array(1) { ["merge_rule_regex"] => bool(false)} 路由參數(shù) -
$match : array(1) { ["name"] => string(1) "1"} 就是上邊三種情況返回的值
執(zhí)行文件:thinkphp/library/think/route/RuleItem.php,行號(hào)202.
接著就會(huì)進(jìn)入到方法parseRule
這個(gè)里邊,這個(gè)方法的功能就是解析匹配到的規(guī)則路由,參數(shù)就是咔咔上邊給寫出來的六個(gè)參數(shù)。
由于路由參數(shù)是沒有設(shè)置的所以不會(huì)去執(zhí)行上邊的那部分,接下來會(huì)對(duì)圈起來的地方進(jìn)行深入的解析。
在這里主要就是替換路由地址中的變量。
這里的route和match這倆個(gè)值在上邊的參數(shù)就已經(jīng)做出說明了,可以翻上去看一下。
可以肯定的是肯定這個(gè)判斷肯定會(huì)進(jìn)行執(zhí)行。
這里注意一下中間的部分,可以看到$replace
和$search
執(zhí)行了倆次。其實(shí)就是針對(duì)路由規(guī)則后邊的地址進(jìn)行了倆種方案。
路由規(guī)則后邊的參數(shù)是可選的,所以說這倆個(gè)值分別為以下,請(qǐng)看圖。
然后通過str_replace() 函數(shù)替換字符串中的一些字符(區(qū)分大小寫)。
最后返回的route就是string(17) "index/index/hello"
接下來就是咔咔圈出來的地方,這塊主要就是運(yùn)用PHP函數(shù)來對(duì)請(qǐng)求地址進(jìn)行的處理。
這里有一個(gè)方法作用是解析URL地址中的參數(shù)Request對(duì)象,但是因?yàn)閁RL在這里是個(gè)空值所以不會(huì)去執(zhí)行。
在將三個(gè)值進(jìn)行賦值,然后就開始執(zhí)行了路由調(diào)度。
本節(jié)就簡單說到這里,在本節(jié)主要就是解析匹配到的規(guī)則路由,接下來就是進(jìn)行路由調(diào)度。
路由調(diào)度是路由這塊的最后一個(gè)流程,也是連接控制器的一個(gè)點(diǎn),接下來咔咔會(huì)對(duì)路由調(diào)度進(jìn)行詳細(xì)解析。
續(xù)集
在解析匹配到的規(guī)則路由
中存在這行代碼,在上文中沒有做出對(duì)應(yīng)情況說明,接下來對(duì)這種情況做出說明。
路由地址設(shè)置為如下。
此時(shí)在來打印一下剛剛那塊的代碼查看一下變化,到底有什么作用。
最后就是通過str_replace
進(jìn)行替換的,所以并將參數(shù)換成hello。
這里有一個(gè)非常重要的一個(gè)點(diǎn)就是關(guān)于str_replace
這個(gè)函數(shù)的高級(jí)使用,平時(shí)都是用一個(gè)字符串替換另一個(gè)字符串,但是在本案例中是數(shù)組替換數(shù)組的方式。
如果你之前沒有使用過這種方式,請(qǐng)自行搜索或者持續(xù)關(guān)注咔咔的發(fā)文,你會(huì)看到你想要的。
二、路由調(diào)度
在路由的這一節(jié)中這是咔咔最后講解的一個(gè)重點(diǎn),路由調(diào)度。
路由調(diào)度完就是控制器的執(zhí)行了,不是說路由設(shè)置完就可以直接訪問的。
在解析匹配到的規(guī)則路由
的最后一步就會(huì)執(zhí)行路由調(diào)度。
執(zhí)行文件 : thinkphp/library/think/route/Rule.php 763行.
參數(shù)說明
-
$request : object(thinkRequest) 請(qǐng)求類 -
$route : string(17) "index/index/hello" -
$option : array(1) { ["merge_rule_regex"] => bool(false)}
那么就來到發(fā)起路由調(diào)度的方法來進(jìn)行深度解析。
在這個(gè)方法中咔咔只對(duì)最常用的方式進(jìn)行解析了,其它的方式根據(jù)自己閱讀源碼的方式進(jìn)行閱讀即可。
來到解析URL地址為 模塊/控制器/操作中。
關(guān)于這個(gè)list的使用在源碼中也出現(xiàn)了很多次了,咔咔將打印結(jié)果給大家展示出來。、
打印的數(shù)據(jù)為$this->parseUrlPath($route);
接下來在一張圖中進(jìn)行打印$path
和$var
的值,你們就知道這個(gè)list是怎么使用的。
從下圖中就可以看到list其實(shí)就是將數(shù)組的索引值賦值給list中的倆個(gè)變量而已。
接下來就是獲取操作,控制器,模塊。
函數(shù)array_pop
就是返回?cái)?shù)組的最后一組數(shù)據(jù)然后返回,在這里也就是返回的操作。
控制器也是用同樣的操作。
模塊是會(huì)在配置文件中獲取,最終也是通過array_pop
來進(jìn)行獲取的。
至于使用請(qǐng)求類來獲取請(qǐng)求方式,這個(gè)在后期會(huì)進(jìn)行解析,這里只需知道返回的是請(qǐng)求方式即可。
最終的返回結(jié)果如下圖。
在這里有一個(gè)問題,就是關(guān)于類的調(diào)用問題,跟這咔咔的節(jié)奏一點(diǎn)一點(diǎn)追蹤。
路由到模塊/控制器/操作類的調(diào)用關(guān)系
追蹤這個(gè)函數(shù)第一步是進(jìn)入到了類thinkphp/library/think/route/Rule.php
這里
然后在進(jìn)行追蹤Modul這個(gè)類。
又因?yàn)檫@個(gè)類繼承著Dispatch這個(gè)類,所以還需要在繼續(xù)追蹤。
來到thinkphp/library/think/route/Dispatch.php
就可以看到這個(gè)構(gòu)造函數(shù),到這里也就是最后一步了。
然后在通過本類thinkphp/library/think/route/Dispatch.php
的init方法,返回本類,也就是上層打印出來的結(jié)果。
在這里可以對(duì)這個(gè)返回結(jié)果做一個(gè)調(diào)試看一下結(jié)果。
通過結(jié)果就知道最終就是從這里返回過去的。
三、路由調(diào)度的最終結(jié)果返回給了誰?
路由調(diào)度的解析在這里就結(jié)束了,但是經(jīng)過了一層一層的深扒已經(jīng)進(jìn)入到了框架的最底層位置了。
這個(gè)時(shí)候突然給返回了一個(gè)值,是不是有點(diǎn)懵,這是返回到哪里去了。
根據(jù)咔咔畫的思維導(dǎo)圖先來捋一遍。
-
路由到模塊/控制器/操作$this->dispatchModule -
發(fā)起路由調(diào)度$this->dispatch -
解析匹配到的規(guī)則路由return $this->parseRule -
執(zhí)行 $this->checkRule檢測(cè)路由 -
執(zhí)行thinkrouteRuleItem Object 中的check -
檢查分組路由 -
檢測(cè)分組路由 : parent::check -
檢測(cè)域名路由 -
路由檢測(cè): this->route->check(must); -
路由檢測(cè) : $this->routeCheck()->init()
所以說根據(jù)咔咔的導(dǎo)圖最開始的位置就是$this->routeCheck()->init()
如果圖不清晰請(qǐng)及時(shí)在評(píng)論區(qū)見。
也就是返回到了下圖位置。
然胡使用咔咔提供的神器來打印一下執(zhí)行流程。
這里跟上邊那個(gè)無序列表時(shí)反向的,跟這個(gè)流程執(zhí)行也是一一致的。
截止到這里關(guān)于路由的所有內(nèi)容就結(jié)束了,在路由這節(jié)有很多的內(nèi)容,也不會(huì)去全面的解讀,抓住要點(diǎn)進(jìn)行解析即可。
總結(jié)
在這一節(jié)中主要針對(duì)解析匹配到的規(guī)則路由-路由地址動(dòng)態(tài)處理,主要就是針對(duì)不同的路由規(guī)則參數(shù),返回不同倆種結(jié)果。
主要就是針對(duì)上文中的一種情況就是路由規(guī)則和路由地址都帶有參數(shù)時(shí)對(duì)參數(shù)進(jìn)行的處理。
然后使用array_pop進(jìn)行獲取模塊控制器方法,最終執(zhí)行到路由調(diào)度。
在路由調(diào)度后一定要清晰的知道關(guān)于返回值是返回給了哪里,對(duì)執(zhí)行的流程一定明確,可以根據(jù)咔咔給出的導(dǎo)圖,或者使用神器來打印也可以。
路由源碼解析到這里就大結(jié)局了,從應(yīng)用初始化開始到路由調(diào)度返回值,這一個(gè)過程中有很多的過程,咔咔也僅僅是針對(duì)重要的進(jìn)行了解析。
后期如有時(shí)間也會(huì)對(duì)其它情況進(jìn)行詳細(xì)的說明,路由這塊也是框架最復(fù)雜的一部分,希望可以好好進(jìn)行理解。