Laravel — The Basics — Routing (官方文件原子化翻譯)
By: Ray Lee
Tags: Dev, PHP, Backend, Documentation, Laravel

Photo by Justin Lawrence on Unsplash

# 前言

我喜歡使用 Laravel 開發的感覺, 除了開發快速, 程式碼簡潔且優雅之外, Laravel 框架本身也是一個很好的學習參照物。 本篇主要將官方文件重點整理成 Q&A 的形式呈現, 原子化的概念, 這方式並不適用於每個人, 但若對你有幫助, 我會很開心。

# 版本

Laravel 7.x

# Basic Routing

# Available Router Methods

以下的 Laravel example code 的意思是？

Example:

<?php

Route::match(['get', 'post'], '/', function () {

//

});



Route::any('/', function () {

//

});

Answer:

<?php

// 該 route 可以接收 get 以及 post HTTP method request

Route::match(['get', 'post'], '/', function () {

//

});



// 該 route 可以接收任何 HTTP method 的 request

Route::any('/', function () {

//

});

# CSRF Protection

Laravel 中, 哪些 HTTP method 會有 CSRF Protection?

POST

PUT

DELETE

Laravel 的 CSRF Protection 中, 是如何將 XSRF TOKEN 傳給前端的？

1. Laravel 把 token 存在 Session 當中

2. 把 Session 對應的 Cookie 傳給前端

3. 前端帶著對應的 Cookie, token 上來

4. Laravel 用 Cookie 找 Session 對應的值, 並驗證前端送來的 token

Laravel => Cookie, token => 前端 => Cookie, token => Laravel

Laravel 的 CSRF Protection 中, XSRF Token 會放在哪裡傳給前端？

Cookie

Laravel 的 CSRF Protection 中, XSRF Token 會否加密再傳給前端？ 會的 Laravel 的 CSRF Protection 中, 後端會傳什麼給前端？

與 Session 相對應的 Cookie 以及寫在 Cookie 內的 token

Laravel 的 CSRF Protection 中, 前端會傳什麼給後端？

後端之前傳來的 Cookie 資訊以及裡頭的 token

# Redirect Routes

HTTP 轉址中, 301 跟 302 差在哪？

301: 永久轉址, 搜尋引擎會把新網址當作唯一 url

302: 暫時轉址, 搜尋引擎會知道這只是暫時的

以下的 Laravel example code 的意思是？

Example:

<?php

Route::redirect('/here', '/there');

Answer: 將 uri 為 /here 的 request 轉址到 /there

以下的 Laravel example code 的意思是？

Example:

<?php

Route::redirect('/here', '/there', 301);

Answer: 將 uri 為 /here 的 request 轉址到 /there , 並帶上狀態碼

以下的 Laravel example code 的意思是？

Example:

<?php

Route::permanentRedirect('/here', '/there');

Answer: 將 uri 為 /here 的 request 轉址到 /there , 並帶上狀態碼 301

# View Routes

以下的 Laravel example code 的意思是？

Example:

<?php

Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

Answer: 收到 /welcome request, 導向 welcome view page, 帶著參數 ['name' => 'Taylor'] 過去

# Route Parameters

# Required Parameters

以下的 Laravel example code 的意思是？

Example:

<?php

Route::get('user/{id}', function ($id) {

return 'User '.$id;

});

Answer: 假如收到 request user/2, 那 $id 便會是 2

以下的 Laravel example code 的意思是？

Example:

<?php

Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {

//

});

Answer: 當收到 request **posts/1/comments/2 時, $postId 為 1, $commentId 為 2, 看順序取值

Laravel 中, 定義 URL 中的參數時, 可以用 - 嗎？ 如果不行, 那要用什麼?

不可 可使用 underscore ( _ )

Laravel 中, 取得從 URL 中定義的參數時, 是看名字, 還是看順序？

順序, controller 參數的名字不重要, 隨便亂取都可以, 只看順序

以下的 Laravel example code 中, 假設 a = 1, b = 2, 那 dd() 的結果是？

Example:

<?php

public function index($d, MerchantDepositIndex $request, $c, DepositManager $manager)

{

dd($c, $d); // 結果是？

}



Route::apiResource('deposits/{a}/{b}', 'DepositController')->only(['index', 'show']);

Answer: 2, 1 Laravel 會自動找到參數並按照帶入的順序排列

# Optional Parameters

以下的 Laravel example code 的意思是？

Example:

<?php

Answer:

<?php

以下的 Laravel example code 的意思是？

Example:

<?php

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

return $name;

});



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

return $name;

});

Answer:

<?php

// 定義 optional 的 uri parameter, 可定義預設值

// 若是不使用 `?`, 則一定要帶值, 不可事先定義

// 若沒帶值, 例如 request 為 'example.com/user', 則 $name = null

// 若有帶值, 例如 request 為 'example.com/user/2', 則 $name = 2

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

return $name;

});



// 若沒帶值, 例如 request 為 'example.com/user', 則 $name = 'John'

// 若有帶值, 例如 request 為 'example.com/user/2', 則 $name = 2

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

return $name;

});

# Regular Expression Constraints

以下的 Laravel example code 的意思是？

Example:

<?php

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]+']);

Answer: 對 url parameter 加上正則的驗證, 格式須符合正則規則

# Global Constraints

以下的 Laravel example code 的意思是？

Example:

<?php

public function boot()

{

Route::pattern('id', '[0-9]+');



parent::boot();

}

Answer: 在 RouteServiceProvider 針對 url parameter 定義一個 global 的正則規則, 此規則作用範圍為所有的 url parameter

以下的 Laravel example code 的意思是？

Example:

<?php

Route::get('search/{search}', function ($search) {

return $search;

})->where('search', '.*');

Answer: 允許 {search} url parameter 以任何格式, 像是 / 也允許

在 Laravel 中, 如果我想要定義一個 URL parameter, 這個 parameter 可能是一個 / , 那只有在 URL 的哪一個位置是容許的？

最後一個區塊

# Named Routes

以下的 Laravel example code 的意思是？

Example:

<?php

Route::get('user/profile', function () {

//

})->name('profile');



Route::get('user/profile', 'UserProfileController@show')->name('profile');

Answer: 將該 route 命名為 profile, 之後可以使用, 例如 redirect()->route('profile')

以下的 Laravel example code 的意思是？

Example:

<?php

// Generating Redirects...

return redirect()->route('profile');

Answer: redirect 到已命名為 name 的 route

以下的 Laravel example code 的意思是？

Example:

<?php

// Generating URLs...

$url = route('profile');

Answer: 取得名為 profile 的 route url

以下的 Laravel example code 的意思是？

Example:

<?php

Route::get('user/{id}/profile', function ($id) {

//

})->name('profile');



$url = route('profile', ['id' => 1]);

Answer: 命名一個 route 為 profile 再取得名為 profile 的 route url, 並帶入 id 為 1

在以下 Laravel 的 route 中, 產生的 url 會長怎樣？

Example:

<?php

Route::get('user/{id}/profile', function ($id) {

//

})->name('profile');



$url = route('profile', ['id' => 1, 'photos' => 'yes']);

Answer: /user/1/profile?photos=yes

以下的 Laravel example code 的意思是？

Example:

<?php

Route::get('user/{id}/profile', function ($id) {

//

})->name('profile');



$url = route('profile', ['id' => 1, 'photos' => 'yes']);



// /user/1/profile?photos=yes

Answer: 命名為 profile 的 route, 並取得名為 profile 的 route url, 帶入 url parameter id, 因為 photos 並沒有被定義在 route url parameter, 因此在 url 中會以 query 呈現

以下的 Laravel example code 的意思是？

Example:

<?php

public function handle($request, Closure $next)

{

if ($request->route()->named('profile')) {

//

}



return $next($request);

}

Answer: 判斷當前 request 的 route 是否名為 profile

# Route Groups

# Middleware

以下的 Laravel example code 的意思是？

Example:

<?php

Route::middleware(['first', 'second'])->group(function () {

Route::get('/', function () {

//

});



Route::get('user/profile', function () {

//

});

});

Answer: 為複數 route 定義複數 middleware 對 example 中的兩個 route 的 request 都將必須通過 ‘first’, ‘second’ 兩個 middleware

# Namespaces

以下的 Laravel example code 的意思是？

Example:

<?php

Route::namespace('Admin')->group(function () {

//

});

Answer: 將 namespace ‘Admin’ 套用到 closure 內的所有 controller

# Sub-Domain Routing

以下的 Laravel example code 的意思是？

Example:

<?php

Route::domain('{account}.myapp.com')->group(function () {

Route::get('user/{id}', function ($account, $id) {

//

});

});

Answer: domain 為 {account}.myapp.com 的 request 都會到 example 中的 route, 並且從 domain 取得 account parameter, 以及從 url 中取得 id parameter

在 Laravel 中, 為了確保 sub-domain routing 可被存取, 當我們在定義時, 應該先定義 sub-domain routes 還是 root domain routes?

sub-domain routes

# Route Prefixes

以下的 Laravel example code 的意思是？

Example:

<?php

Route::prefix('admin')->group(function () {

Route::get('users', function () {



});

});

Answer: 將 prefix ‘admin’ 作用到 group 內的 route, 所以 request 的 url 為 /admin/users

以下的 Laravel route 將符合什麼樣的 URL ?

Example:

<?php

Route::prefix('admin')->group(function () {

Route::get('users', function () {

});

});

Answer: /admin/users

# Route Name Prefixes

以下的 Laravel example code 的意思是？

Example:

<?php

Route::name('admin.')->group(function () {

Route::get('users', function () {

//

})->name('users');

});

Answer: closure 內的 routes 的 name 都會有 ‘admin.’ 這個前綴, 所以 example 中的 route name 為 ‘admin.users’

# Route Model Binding

# Implicit Binding

以下的 Laravel example code 的意思是？

Example:

<?php

Route::get('api/users/{user}', function (App\User $user) {

return $user->email;

});

Answer: 新增 {user} url parameter, 透過 function() 內的 model binding, 可直接透過 $user 取得 User model, 預設透過 primary_key 取得

Laravel 中, 如果 Model Binding 沒有找到相對應的 Model, 會回傳什麼？?

404

# Customizing the key Name

以下的 Laravel example code 的意思是？

Example:

<?php

class User extends Authenticatable;

{

public function getRouteKeyName()

{

return 'slug';

}

}

Answer: model binding 中, 預設使用 primary_key 取得 model, 可在 model 中使用 getRouteKeyName() 來定義使用 ‘slug’ column 來取得 model

# Explicit Binding

以下的 Laravel example code 的意思是？

Example:

<?php

public function boot()

{

parent::boot();



Route::model('user', App\User::class);

}

Answer: 如果不想使用 type-hinted variable 來實現 model binding, 想要經由 url 的 parameter name 來實現 model binding 的話, 可以再 RouteServiceProvider 的 boot method 使用 Route class 的 model method 來將 url 中的 ‘user’ parameter 與 ‘App\User’ model 相關聯

# Customizing The Resolution Logic

Laravel 的 model binding 中, 如果我想要定義比單一 column 更複雜的規則, 有哪兩種做法？

RouteServiceProvider 增加規則 在 Model 中定義 method

以下的 Laravel example code 的意思是？

Example:

<?php

class User extends Authenticatable

{

public function resolveRouteBinding($value)

{

return $this->where('name', $value)->firstOrFail();

}

}

Answer: 在 model 中定義 model binding 的規則, 比方說, 當我在 controller 使用 model binding, (User $user), 則取得 $User->where(‘name’, $value)->firstOrFail() 的 model

以下的 Laravel example code 的意思是？

Example:

<?php

public function boot()

{

parent::boot();



Route::bind('user', function ($value) {

return App\User::where('name', $value)->firstOrFail();

});

}

Answer: 從 RouteServiceProvider 的 boot() 定義 model binding 規則, 當 binding 指定的 Model 為 User 時, 會到 User Model 以 where(‘name’, $value)->firstOrFail() 的方式取得 model

# Fallback Routes

以下的 Laravel example code 的意思是？

Example:

<?php

Route::fallback(function () {

//

});

Answer: 預設未找到 route 的 request 會回傳 404, 可透過自定義 fallback route 來定義後續動作

在 Laravel 中, fallback route 的位置應該要放在什麼地方？

最後

# Rate Limiting

以下的 Laravel example code 的意思是？

Example:

<?php

Route::middleware('auth:api', 'throttle:60,1')->group(function () {

Route::get('/user', function () {

//

});

});

Answer: 使用 auth:api middleware 來驗證 user, 使用 throttle middleware 來限制 1 分鐘最多可存取 60 次

以下的 Laravel example code 的意思是？

Example:

<?php

Route::middleware('throttle:10|60,1')->group(function () {

//

});

Answer: 使用 throttle middleware 來限制存取次數, authenticated user 1 分鐘最多可存取 60 次, 而 unauthenticated user 1 分鐘最多存取 10 次

# Dynamic Rate Limiting

以下的 Laravel example code 的意思是？

Example:

<?php

Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {

Route::get('/user', function () {

//

});

});

Answer: 使用 auth:api middleware 來驗證 user, 使用 throttle middleware 來動態的限制使用者存取次數 rate_limit 代表 authenticated user 在資料庫內的欄位, 須為數字, 代表 1 分鐘內可存取次數的上限

# Distinct Guest & Authenticated User Rate Limits

以下的 Laravel example code 的意思是？

Example:

<?php

Route::middleware('auth:api', 'throttle:10|rate_limit,1')->group(function () {

Route::get('/user', function () {

//

});

});

Answer: unauthenticated user 1 分鐘最多訪問 10 次 authenticated user 1 分鐘最多訪問次數定義在 user 的 rate_limit column

# Form Method Spoofing

使用 HTML Form 發 API 時, 常常遇到 PUT, PATCH, DELETE 方法不可用, 根本的原因是什麼？

HTML Forms 不支援以上的 HTTP method

哪幾種 HTTP method 是不被 HTML Form 支援的？

PUT, PATCH, DELETE

以下的 Laravel example code 的意思是？

Example:

<form action="/foo/bar" method="POST">

<input type="hidden" name="_method" value="PUT">

<input type="hidden" name="_token" value="{{ csrf_token() }}">

</form>

Answer: 讓 HTML form 可以支援 PUT, PATCH, DELETE 等 HTTP Method

以下的 Laravel example code 的意思是？

Example:

<form action="/foo/bar" method="POST">

@method('PUT')

@csrf

</form>

Answer: 讓 HTML form 可以支援 PUT, PATCH, DELETE 等 HTTP Method, 使用 blade 的方法來發 PUT method

# Accessing The Current Route

以下的 Laravel example code 的意思是？

Example:

<?php

$name = \Illuminate\Support\Facades\Route::currentRouteName();

Answer: 取得當前 route name

以下的 Laravel example code 的意思是？

Example:

<?php

$name = \Illuminate\Support\Facades\Route::current();

Answer: 取得當前的 route object

以下的 Laravel example code 的意思是？

Example:

<?php

$name = \Illuminate\Support\Facades\Route::currentRouteAction();

Answer: 取得當前 request 存取的 controller

Laravel 中, route 的 action 長什麼樣子？

App\Http\Controllers\Admin\controllerName@controllerMethodName

下面提供所以可以被取得的 route method

underlyingClass of the Route facade

Route instance