引言
上一章內容我們介紹了使用laravel路由動詞定義方便的url,以及通過url引數繫結傳遞資料,本文我們繼續深入Route功能,學習一些提升生產力的方法,在現實場景中也非常實用。
“暱稱”
如果你的應用程式路由條目可以達到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領域原創作者
本作品採用《CC 協議》,轉載必須註明作者和本文連結