3.1 - Laravel - 5.6 - Route - Group方法

HarveyNorman發表於2020-09-20

group方法在路由中起到對固定一批路由統一規則的作用。
他也用於載入路由配置檔案web.php,laravel本身把整個路由配置檔案視為一個路由group操作。
直接看程式碼:

public function group(array $attributes, $routes)
{
    $this->updateGroupStack($attributes);
    $this->loadRoutes($routes);
    array_pop($this->groupStack);
}

這裡主要是三步:

1.首先使用updateGroupStack方法更新groupStack陣列。
$this->updateGroupStack($attributes);

groupStack陣列用來儲存所有group的attribute資訊。比如middleware,namespace,prefix

updateGroupStack原始碼如下:

protected function updateGroupStack(array $attributes)
{
    if (! empty($this->groupStack)) {
        $attributes = $this->mergeWithLastGroup($attributes);
    }

    $this->groupStack[] = $attributes;
}

很簡單,如果groupStack這個陣列不為空,就使用mergeWithLastGroup方法merge當前的attributes到groupStack陣列的最後一個資料中。
否則就直接把當前這個group的attributes作為整個資料新增到groupStack陣列中。

1.1 看下mergeWithLastGroup方法。

public function mergeWithLastGroup($new)
{
    return RouteGroup::merge($new, end($this->groupStack));
}

a.end($this->groupStack)獲取groupStack最後一個資料。
b.呼叫RouteGroup的merge方法組合attributes和group中的最後一個資料。

這裡的merge方法包含很多的規則,具體參考 3.2 - Laravel - 5.6 - Route - 路由group合併。


2.回到group方法,第二步$this->loadRoutes($routes); 載入路由
完成更新groupstack後,使用loadRoutes載入路由。

protected function loadRoutes($routes)
    {
        if ($routes instanceof Closure) {
            $routes($this);
        } else {
            (new RouteFileRegistrar($this))->register($routes);
        }
    }

a.如果這個$routes是一個閉包函式,就直接執行。
b.否則建立一個RouteFileRegistrar物件來呼叫register方法註冊這個$routes

2.1 我們看下RouteFileRegistrar的register方法。

public function register($routes)
    {
        $router = $this->router;
        require $routes;
    }

很明瞭,就是使用require引入$routes

說明$routes可以是一個路徑。


** 第二步總結:**
1.到這裡就很明確了。這一步$this->loadRoutes($routes); 簡單說就是:如果group方法提供的引數是閉包函式,比如下面這種。

Route::group(['middleware' => ['auth', 'verified']], function() {
    Route::get('user_addresses', 'UserAddressesController@index');
....

,這裡就會執行這個路由的閉包函式。也就是載入這個路由。

2.否則則會判定是一個檔案路徑,會使用require引入這個檔案。然後依然執行檔案中的方法。
這種檔案路徑的具體的使用的例子是在 載入路由配置檔案web.php,api.php的時候使用。路由前期初始化的時候載入配置檔案呼叫的group方法如下:

protected function mapWebRoutes()
{
    Route::middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/web.php'));
}

載入配置檔案的具體流程會在 載入RouteServiceProvider中涉及。

3.最後完成路由的載入後,需要從groupStack中去除剛剛已經建立的路由。不重複執行。在第一步新增的路由屬性資料要在第三步刪除,保證當前載入的路由group屬性attributes不針對其他路由。

總結,路由的group方法在Router物件中提供。group方法提供了兩種方式來進行路由的載入,一個是閉包,一個是檔案路徑的方式。

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

相關文章