Laravel 之路由匹配

Dennis_Ritchie發表於2019-12-22

前言

在閱讀這篇文章之前,我希望你閱讀了老司機帶你實現 Laravel 之管道老司機帶你實現 Laravel 路由註冊功能,還有老司機帶你深入理解 Laravel 中介軟體(全域性中介軟體),它們是閱讀這篇文章的基礎。

流程分析

廢話不多說,我們們直接分析Laravel程式碼,上次我們分析Laravel全域性的全域性中介軟體,程式碼如下所示:

picture alt

全域性中介軟體執行完之後,會呼叫dispatchToRouter方法返回的回撥方法,我們看一下這個方法:

picture alt

當前類Illuminate\Foundation\Http\Kernel$router屬性是Illuminate\Routing\Router類的物件,下面我們看
Illuminate\Routing\Router類的dispatch方法,如下:

picture alt

繼續呼叫dispatchToRoute方法,如下:

picture alt

我們今天的重點是findRoute方法,也就是尋找路由。

picture alt

Router類的routes屬性是一個Illuminate\Routing\RouteCollection類的例項,我們註冊的所有路由都儲存在這個類的例項中,下面我們進入到的Illuminate\Routing\RouteCollection類的match方法中,如下:

picture alt

在下面的講解中,我們以get請求為例,上面首先呼叫當前物件的get方法,這個方法返回註冊的所有的get請求路由,接下來呼叫matchAgainstRoutes方法,這個方法有必要說一下:

picture alt

在講上面的程式碼之前,我要提到Laravel的回退路由,這是啥呢?Laravel官方的文件:Fallback Routes,我先截圖如下:

picture alt

關於回退路由的解釋我上面說過了。回到matchAgainstRoutes方法中,這個方法分為2部分,第一部分把所有的get路由分為2個容器,第一個容器只包含回退路由,第二個容器包含除去回退路由的所有get路由。第二部分把上面的2個容器合併,注意了此時的回退路由在所有get路由的的最後面。合併完之後遍歷容器中的每一個路由,找到第一個符合規則的路由,上面的first方法的每一個引數都是我們註冊的路由物件,Laravel中的每一個路由物件都是Illuminate\Routing\Route類的例項,下面我們進入到這個方法中:

picture alt

首先呼叫compileRoute方法,該方法如下:

picture alt

這個方法會返回一個\Symfony\Component\Routing\CompiledRoute類的物件,我們先來看一下Illuminate\Routing\RouteCompile類的compile方法:

picture alt

在上面的程式碼中,Laravel本身做的事情非常少,提取可選引數,並把可選引數,路由引數定義等資訊傳遞給\Symfony\Component\Routing\CompiledRoute類,剩下的事情就不管了,由於Laravel這裡呼叫的是第三方元件Symfony的程式碼,所以我們在這裡暫不分析,你只需要知道這些就行(以後再給大家仔細分析),好了,經過上面的這些流程,我們返回到Illuminate\Routing\Route類的matches方法中,執行如下程式碼:

picture alt

方法getValidators返回了一個由Illuminate\Routing\Matching\ValidatorInterface介面例項組成的例項陣列:

picture alt

我們任意分析一個,就以為例Illuminate\Routing\Matching\MethodValidator類為例:
picture alt

它的matches方法檢測當前請求的方法是不是合法的請求方法,回到matches方法中,如果所有的ValidatorInterface返回為true,matches方法才會返回true,否則為false。

其它的ValidatorInterface都是一樣的,不再詳述。

總結

經過上面簡要的分析,對於你弄懂Laravel的路由匹配已經足夠了,祝您學習愉快。

如果有不懂的地方,可以加我的qq:1174332406,或者是微信:itshardjs

相關文章