前言
在閱讀這篇文章之前,我希望你閱讀了老司機帶你實現 Laravel 之管道和老司機帶你實現 Laravel 路由註冊功能,還有老司機帶你深入理解 Laravel 中介軟體(全域性中介軟體),它們是閱讀這篇文章的基礎。
流程分析
廢話不多說,我們們直接分析Laravel程式碼,上次我們分析Laravel全域性的全域性中介軟體,程式碼如下所示:
全域性中介軟體執行完之後,會呼叫dispatchToRouter
方法返回的回撥方法,我們看一下這個方法:
當前類Illuminate\Foundation\Http\Kernel
的$router
屬性是Illuminate\Routing\Router
類的物件,下面我們看Illuminate\Routing\Router
類的dispatch
方法,如下:
繼續呼叫dispatchToRoute
方法,如下:
我們今天的重點是findRoute
方法,也就是尋找路由。
Router
類的routes
屬性是一個Illuminate\Routing\RouteCollection
類的例項,我們註冊的所有路由都儲存在這個類的例項中,下面我們進入到的Illuminate\Routing\RouteCollection
類的match
方法中,如下:
在下面的講解中,我們以get請求為例,上面首先呼叫當前物件的get
方法,這個方法返回註冊的所有的get請求路由,接下來呼叫matchAgainstRoutes
方法,這個方法有必要說一下:
在講上面的程式碼之前,我要提到Laravel的回退路由,這是啥呢?Laravel官方的文件:Fallback Routes,我先截圖如下:
關於回退路由的解釋我上面說過了。回到matchAgainstRoutes
方法中,這個方法分為2部分,第一部分把所有的get路由分為2個容器,第一個容器只包含回退路由,第二個容器包含除去回退路由的所有get路由。第二部分把上面的2個容器合併,注意了此時的回退路由在所有get路由的的最後面。合併完之後遍歷容器中的每一個路由,找到第一個符合規則的路由,上面的first
方法的每一個引數都是我們註冊的路由物件,Laravel中的每一個路由物件都是Illuminate\Routing\Route
類的例項,下面我們進入到這個方法中:
首先呼叫compileRoute
方法,該方法如下:
這個方法會返回一個\Symfony\Component\Routing\CompiledRoute
類的物件,我們先來看一下Illuminate\Routing\RouteCompile
類的compile方法:
在上面的程式碼中,Laravel本身做的事情非常少,提取可選引數,並把可選引數,路由引數定義等資訊傳遞給\Symfony\Component\Routing\CompiledRoute
類,剩下的事情就不管了,由於Laravel這裡呼叫的是第三方元件Symfony
的程式碼,所以我們在這裡暫不分析,你只需要知道這些就行(以後再給大家仔細分析),好了,經過上面的這些流程,我們返回到Illuminate\Routing\Route
類的matches
方法中,執行如下程式碼:
方法getValidators
返回了一個由Illuminate\Routing\Matching\ValidatorInterface
介面例項組成的例項陣列:
我們任意分析一個,就以為例Illuminate\Routing\Matching\MethodValidator
類為例:
它的matches方法檢測當前請求的方法是不是合法的請求方法,回到matches
方法中,如果所有的ValidatorInterface
返回為true,matches
方法才會返回true,否則為false。
其它的ValidatorInterface
都是一樣的,不再詳述。
總結
經過上面簡要的分析,對於你弄懂Laravel的路由匹配已經足夠了,祝您學習愉快。