3.3 - Laravel - 5.6 - Route - 載入單個Route例項的主要流程

HarveyNorman發表於2021-06-18

前面涉及了laravel如何對路由配置檔案的載入過程的細節,這章節來看下單個路由例項的載入流程。也就是路由配置檔案中 get post 這些常用方法的原始碼邏輯。

1.我們從一個例子入手:

Route::get('connect', 'AccountController@connect')->name('connect');

首先這裡的Route是一個facade,對應的類是Illuminate\Routing 下的
Router類。

注意是Router類 不是Route類。注意區分。
這個地方非常不好的是 宣告瞭一個Router的Facade,返回的卻是Route。容易混淆。不知道有什麼特殊的目的。

這個Router類會實現介面,BindingRegistrar 和 RegistrarContract

class Router implements BindingRegistrar, RegistrarContract{...}

2.然後我們可以找到Router類下的get方法原始碼

public function get($uri, $action = null)
    {
        return $this->addRoute(['GET', 'HEAD'], $uri, $action);
    }

2.1 可以看到get方法就是呼叫了addRoute方法。post put 等方法也雷同,最後都是呼叫的addRote方法,只是相應傳入不一樣的引數而已。

這裡注意get方法傳入的第一個引數是一個陣列[‘GET’, ‘HEAD’],可以看到當你呼叫get方法時 laravel 在這裡是集中處理http的head和get方法的。

2.2 接著看下addRoute方法的原始碼:也是主要邏輯程式碼

public function addRoute($methods, $uri, $action)
    {
        return $this->routes->add($this->createRoute($methods, $uri, $action));
    }

a.首先這裡的變數$routes 是一個RouteCollection例項,在當前類Router例項化的時候(也就是laravel初始化的時候) 會在建構函式中進行初始化。參看下面建構函式程式碼:

看RouteCollection這個名字,應該是儲存所有Route物件的一個集合類。先不去管它。

public function __construct(Dispatcher $events, Container $container = null)
    {
        $this->events = $events;
        $this->routes = new RouteCollection;
        $this->container = $container ?: new Container;
    }

b.然後變數$routes呼叫的add()方法就是RouteCollection提供的add方法,
此 add 方法程式碼如下:

public function add(Route $route)
    {
        $this->addToCollections($route);

        $this->addLookups($route);

        return $route;
    }

add方法的分析放在了其他小節,這裡可以提前知道的是:這個方法的目的就是把傳入的$route物件進行儲存。同時會返回這個$route物件。這個route物件就是我們根據上面的給的例子 get方法建立出來的route物件。
具體的分析看章節 RouteCollection的add方法原始碼。

3.第三步就是最重要的步驟 呼叫createRoute方法,建立Route物件。
具體分析放在了下一節:可以知道的是,這就是通過上面的給的例子 get方法建立出來的route物件的邏輯。

$this->createRoute($methods, $uri, $action)

具體流程在下一節 路由物件的建立。


總結:
路由配置檔案對單個路由的載入流程基本上就是:
1.統一呼叫addRoute方法。
2.通過Router類的createRoute方法建立路由
3.把建立的路由物件存入RouteCollection物件中。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章