天天看點

3分鐘短文:Laravel路子真野啊!路由昵稱字首中間件

引言

上一章内容我們介紹了使用laravel路由動詞定義友善的url,以及通過url參數綁定傳遞資料,

本文我們繼續深入Route功能,學習一些提升生産力的方法,在現實場景中也非常實用。

3分鐘短文:Laravel路子真野啊!路由昵稱字首中間件

“昵稱”

如果你的應用程式路由條目可以達到300到500條,光是管理這些路由位址不重複,或者是浏覽某些部分的路由,

都将是一件非常考驗腦力的事兒。

有沒有想過,能不能給路由起個名字,友善記憶,不用想着路由定義的多複雜,咱們直接用别名通路?laravel為我們考慮到了,

比如路由這樣寫:

Route::get('members/{id}', 'MembersController@show')->name('members.show');           

這樣定義之後在HTML檔案内比如有 a 标簽,或者 form 表單的 action,填url位址的時候,就可以使用laravel的助手函數,這樣來寫:

<a href="<?php echo route('members.show', ['id' => 14]); ?>">           

這樣使用起來,就好像記一個函數名一樣,然後通過數組傳入綁定的位置參數,一般不容易寫錯,格式化也更好。比如我們之前講述的,使用laravel的 Route::resource() 方法生成 restful 風格的api,那麼如果對一個 Phone 模型相關的接口做别名,大概會是這樣子的:

photos.index
photos.create
photos.store
photos.show
photos.edit
photos.update
photos.destroy           

其實助手函數 route 提供的參數傳入,可以靈活組裝url,比如按照位置傳入的資料,不指定鍵名,按順序傳入:

route('users.comments.show', [1, 2])
// http://myapp.com/users/1/comments/2           

也可以明确鍵名,指定傳入的位置參數:

route('users.comments.show', ['userId' => 1, 'commentId' => 2])
// http://myapp.com/users/1/comments/2           

為了驗證位置參數是否和數組鍵名綁定關系,我們颠倒傳入的參數順序,看看輸出是否如預期:

route('users.comments.show', ['commentId' => 2, 'userId' => 1])
// http://myapp.com/users/1/comments/2           

可見,route函數是按照鍵名綁定到位置參數的。如果傳入的數組比可接受的資料要多,route函數會将其作為 get 方法的 querystring 進行傳遞:

route('users.comments.show', ['userId' => 1, 'commentId' => 2, 'opt' => 'a'])
// http://myapp.com/users/1/comments/2?opt=a           

分組

分而治之,對于有相同類目的路由,應該歸類到一起,成為一個組。這就是路由組的由來。我們來看一下,不附加任何額外的功能的組是如何聲明的:

Route::group([], function () {
    Route::get('hello', function () {
        return 'Hello';
    });
    Route::get('world', function () {
        return 'World';
    });
});           

有了分組,那麼可以手動指定,這個分組内所有注冊的路由,都要經過某個中間件,可以聲明如下:

Route::group(['middleware' => 'auth'], function () {
    Route::get('dashboard', function () {
        return view('dashboard');
    });
    Route::get('account', function () {
        return view('account');
    });
});           

其中這個 'middleware' => 'auth' 的 auth 中間件,是聲明在 app/Http/Kernel.php 檔案内,下面這一段是源碼内自帶的中間件:

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];           

我們可以直接拿來用。當然了,上面的示例是在路由組内引入的中間件。對于極為特殊的中間件功能,不能在路由組内統一引用的,可以放到控制器的構造函數内調用。比如下面的代碼:

class DashboardController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('admin-auth')->only('admin');
        $this->middleware('team-member')->except('admin');
    }
}           

因為控制器類已經繼承了中間件的注冊流程,是以可以有效使用中間件的攔截、驗證功能。

加字首

在規劃路由時,能省則省,功能一緻的放在一起,同時在路由數量多了之後,能夠有效地使用字首區分不同的功能子產品,也是一個很好的實踐。

為一組路由加字首,就想注冊中間件一樣,在配置内手動指定,比如下面這樣:

Route::group(['prefix' => 'api'], function () {
    Route::get('/', function () {
        // 路徑 /api
    });
    Route::get('users', function () {
        // 路徑 /api/users
    });
});           

字首是給url路徑中路由部分指定的,我們還可以為二級域名指定路由,相似地,聲明如下代碼:

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

那麼該路由組内所有路由,就僅對指定的二級域名起作用。當然了二級域名還要使用nginx的反向代理配合使用。

laravel的花樣是真多啊!

不僅如此,我們還可以為路由組聲明是指定的命名空間下的控制器所使用的。這樣,可以通過把相似功能子產品放在相同命名空間下,進而達到路由分組的目的。比如:

Route::group(['namespace' => 'API'], function () {
     // 對應 App\Http\Controllers\API\EventController
    Route::get('api/', 'EventController@index');
});           

寫在最後

laravel是給web藝術家準備的,你想到的,想不到的,基礎的,進階的功能都有了。沒有的,你也可以手動實作輪子夢。從上面注冊的路由方法,大家應該能有所感觸。

Happy coding :-)

我是 @程式員小助手 ,專注程式設計知識,圈子動态的IT領域原創作者

繼續閱讀