Laravel 學習筆記——路由(中間件與路由組)

本文包含如下小節,在閱讀以前建議大體閱讀官方文檔相關部分。php

  • 中間件html

  • 路由組node

中間件

在官方文檔上,這一部分是在路由的後面,但我想把它挪到前面來,這樣更爲合理。laravel

這是什麼呢?ajax

咱們知道,路由是一個過程,分析來自客戶端的請求按照路由規則分發至相應的處理邏輯。但有種狀況,打個比方:後臺。後臺不是全部人都能訪問的,咱們在正式的處理邏輯前,須要作一個驗證,好比驗證是否具備權限或者請求的數據是否合法。json

這時候,路由過程的一部分——中間件就上場了。數組

HTTP 中間件提供一個方便的機制來過濾進入應用程序的 HTTP 請求,例如,Laravel 默認包含了一箇中間件來檢驗用戶身份驗證,若是用戶沒有通過身份驗證,中間件會將用戶導向登陸頁面,然而,若是用戶經過身份驗證,中間件將會容許這個請求進一步繼續前進。app

上述內容來自中文版的laravel5文檔,裏面很好的說明了中間件的做用。在laravel5之前的版本,只有過濾器(路由篩選器),目的和如今 的中間件同樣都是在請求處處理邏輯之間的一箇中間過程,通常用做前置和後置的判斷、驗證。經過中間件咱們能夠在控制器裏專一其自己的邏輯,就比如一個後臺 的控制器,我只須要專一於顯示用戶列表或者文章列表、去處理添加的文章等等,而不須要關注訪問者是不是合法的後臺管理員,驗證權限的工做,應該交由中間 件。經過中間件驗證就會正常處理,不經過就會被重定向或者其餘操做。dom

Laravel默認已經內置了許多中間件,且默認開啓。能夠經過編輯app/Http/Kernel.php來決定是否啓用這些中間件。本身開發的中間件也是在這裏進行註冊的哦。網站

app/Http/Kernel.php中的 $middleware 數組是全局中間件,也就是說,任何一條路由都會被應用這些中間件,好比裏面的CSRF驗證中間件。

有時候咱們不須要全局中間件,這時候能夠將某一箇中間件註冊至app/Http/Kernel.php文件中的$routeMiddleware數組,數組的鍵名是中間件的別名,鍵值是具體的中間件類,如

'auth' => 'App\Http\Middleware\AuthMiddleware'。

具體如何在某一路由上使用特定的中間件咱們下文繼續。

咱們在app/Http/Kernel.php文件中的$routeMiddleware數組註冊了一個獨立中間件,這一中間件可被單獨用綁定在一個路由和路由組上。在路由定義的時候能夠像這樣:

Route::get('admin/profile', ['middleware' => 'auth', function(){
    //}]);

當咱們訪問http://yourdomain/admin/profile的時候,首先會通過全局中間件,而後就是咱們在app/Http/Kernel.php的$routeMiddleware數組中定義的名稱爲auth的中間件。

說了這麼多關於如何定義,那麼中間件類裏面應該是什麼樣的呢?看過文檔的應該知道是這樣的(下面的代碼和文檔裏的有些區別哦):

<?phpnamespace App\Http\Middleware;use Closure;use Auth;class AuthMiddleware {

    /**
     * Run the request filter.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // If the user is not logged in        if (Auth::guest()) {
            if ($request->ajax()) {
                return response('Unauthorized!', 401);
            } else {
                return redirect()->guest('admin/login');
            }
        }

        view()->share('loign', true);
        return $next($request);
    }}

上面這段代碼是已經寫好了的中間件,handle方法裏面的內容就是中間件實際的代碼。

咱們看得出第18~27行代碼大概是一個判斷用戶是否登錄的過程,若是沒有登陸,則判斷請求是不是ajax類型的,ajax類型的請求就返回一個表示「你丫的沒權限」的json數據(理解一下就行),若是是標準的請求就重定向至登錄界面。

若是在中間件中,經過了你的驗證、或者前置的操做邏輯,記得經過代碼return $next($request)(上述例子中28行)將請求導向下一個中間件,若是後面沒有中間件,就會到的處理邏輯(好比控制器等)。

上述中間件是一個前置操做的中間件,什麼意思呢?就是在做用在實際處理邏輯前的中間件,就是一個前置中間件。相反,當一個實際處理邏輯運行完之後經過的中間件,就是一個後置中間件。

後置中間件結構以下:

<?phpnamespace App\Http\Middleware;class AfterMiddleware implements Middleware {

    public function handle($request, Closure $next)
    {
        $response = $next($request);

        // 具體的中間件邏輯代碼
        return $response;
    }}

咱們看得出,區別在於多了個$response = $next($request),返回值也變了。很好理解,$next($request)返回的值是整個請求通過無數具體處理邏輯後產生的最終響應,這個響應通常是一堆html代碼(渲染後的視圖),也多是一個json等等。咱們能夠在中間件裏面對這個響應作最後加工處理,最後返回處理完的結果。

路由組羣

這一塊官方文檔有着十分詳盡的描述,可是彷佛不太容易理解。先說說適用場景。

路由組羣每每適用於給某一類路由分組,給這個路由組分配的中間件、過濾器等,都會被運用到該組內的全部路由。

說白了,路由組就是簡化一部分路由定義過程的。好比,後臺的我都想經過地址http://yourdomain/admin/***訪問,假如我有用戶(user)文章(article)兩個模塊,他們的訪問都要通過一個驗證權限的中間件,我須要這樣定義路由:

Route::get('admin/user', ['middleware' => 'authority', function() {
    // blablabla...}]);Route::get('admin/article', ['middleware' => 'authority', function() {
    // blablabla...}]);

如今只有兩條路由,我多寫幾個admin,middleware沒啥的,但系統龐大之後,每一個都要單獨寫對應的中間件,容易出錯,不易管理。這時候,就應該使用路由組:

Route::group(['prefix' => 'admin', 'middleware' => 'authority'], function() {
    Route::get('user', function() {
        // blablabla...    });
    Route::get('article', function() {
        // blablabla...    });});

同時,利用路由組,定義子域名變得十分容易:

Route::group(['domain' => 'bbs.yourdomain.com'], function() {
    Route::get('topic', function() {
        // blablabla...    });

    Route::get('node', function() {
        // blablabla...    });});

子域名也能夠擁有通配符,以此實現更爲靈活的結構。好比我但願個人網站每個用戶都擁有本身的二級域名,相似於這樣:userA.yourdomain.com,userB.yourdomain.com。這時候能夠這樣寫:

Route::group(['domain' => '{username}.myapp.com'], function(){
    Route::get('profile/{type}', function($username, $type)
    {
        //    });});

能夠經過參數獲取域名上的通配符匹配的值。

除這些之外,路由組帶來的便利至關豐富,在這裏基本把路由組存在的意義說完了,其餘關於路由組的能夠移步至官方文檔瞭解。

相關文章
相關標籤/搜索