Background

最近在學Laravel, 學到感覺自己像個白癡. (怎麼都跟天書一樣, 每個東西都是黑盒子) 但沒辦法既然都要用就得好好學, 所以來紀錄一下 在Laravel中如何用 Route的功能.

Basic

$ php artisan --version
Laravel Framework 5.4.22

一開始先確定一下自己使用Laravel的版本. 版本之間有時候差異還蠻大的. 網路上的資源也都還蠻亂的. 5.1, 5.2, 5.3, 5.4? WTF.

Laravel 5.4 的 route 相關設定都放在 /routes 資料夾下. 包含了四個檔案

  • api.php
  • channels.php
  • console.php
  • web.php

通常我們最常用到的是 web.php & api.php. 那這兩個的差別? 我也不太確定. (畢竟我是新手嗎). 常見的說法是, 隨著項目越來越大,我們需要的定義的路由越來越多,只是按照習慣拆分. 看起來就是為了方便管理而已. (可能還有其他功用我不確定而已)

Available Router Methods

基本在Laravel中提供的 Router方法 (基本上就是對應到Http的方法)

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

CSRF Protection

這邊我就不講這個了, 感覺用Nginx就可以解決的東西. 不確定所以就之後再來研究吧.

Route Parameters

個人不太喜歡下列的寫法, 所以也不特別研究了

Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});
Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
    //
});
Route::get('user/{name?}', function ($name = null) {
    return $name;
});

Route::get('user/{name?}', function ($name = 'John') {
    return $name;
});

抓取參數的程式我個人是習慣寫在controller中, keep router simple.

Some Route Constraints

當然有一些參數可能包含一些的規則, 像電話之類的. 也可以在route檢查. 那這種東西就丟到前端(Javascript) 那邊去檢查就好了. 所以對我來說也沒啥特別的意義. 也不研究. (我好像有點任性)

Route::get('user/{name}', function ($name) {
    //
})->where('name', '[A-Za-z]+');

Route::get('user/{id}', function ($id) {
    //
})->where('id', '[0-9]+');

Route::get('user/{id}/{name}', function ($id, $name) {
    //
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

Named Routes

這功能好像可以幫Route取名字, 這樣之後在view那邊就可以偷懶? 好吧, 我必須說我個人的習慣是view那層的code只會有 html + css + javascript 這樣. 所以不會出現任何php的code. 所以在Laravel中的view的所有功能基本上我是不用的. (前端越來越強大了, 很多事都可以在前端解決, 而且更符合 UX/UI. 我自己的感想是後端很多東西可以拔掉了, 有點肥啊)

Advanced

好啦 基本上這個Section是紀錄 Route中比較進階的應用.

Route Groups

簡單來說就是幫你的 Route 做分類的動作. 這個就蠻有比要的. 之後比較方便管理.

Middleware

如果你有某一群Routes需要經過 Middleware 的處理, 你可以這樣做:

Route::group(['middleware' => 'auth'], function () {
    Route::get('/', function ()    {
        // Uses Auth Middleware
    });

    Route::get('user/profile', function () {
        // Uses Auth Middleware
    });
});

Namespaces

老實說這個我也不確定怎麼用. 但感覺只是偷懶的用法而已. (我果然沒有慧根, 希望有一天我會長大)

Sub-Domain Routing

子網域就是根據 URL 的 sub-domain name 來分派到不同的routes.

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

Route Prefixes

prefix 這個功能可能就是我比較常用的方式了. 透過 URL 的 prefix 來管理 routes. 這個可能是我覺得最直接可以對應到 controller 的方式.

Route::group(['prefix' => 'admin'], function () {
    Route::get('users', function ()    {
        // Matches The "/admin/users" URL
    });
});

Route::Resource

講一下這個是幹嘛的. 他主要要解決下面這個問題, 下面是一個常見的 Routes

Route::get('user/all_user', 'UserController@getAllUser'); Route::get('user/{id}/get', 'UserController@getUser'); Route::post('user/create', 'UserController@createUser'); Route::put('user/{id}/update', 'UserController@updateUser'); Route::delete('user/{id}/delete', 'UserController@deleteUser');

當然這樣寫也沒什麼不好, 其實已經蠻單純了. 但如果你的應用是很肥大的, 有時候你還是會看得很煩. 那這時候 Route::Resource 的功用就出來了.

Route::resouce('user', 'UserController'); 

只要一行就可以讓系統de fault 產生基本的 routes 對應到 UserController.

/user => index(GET) # index: 通常用於 query 全部資料
/user/create => create(GET) # 新增資料
/user => store(POST) # 建立新資料
/user/{id} => show(GET) # 用於取得單筆資料
/usr/{id}/edit => edit(GET) # 編輯資料
/user/{id} => update(PUT/PATCH) # 更新單筆資料
/user/{id} => destroy(DELETE) # 刪除單筆資料

但不夠用的部分再另外加上去就好.

Reference