# Introduction
學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣造一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。
# 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 | 
Laravel 的 CSRF Protection 中, 是如何將 XSRF TOKEN 傳給前端的?
| 1. Laravel 把 token 存在 Session 當中 | 
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 | 
以下的 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:
 預設在 controller method inject model binding 時, 像是index(User $user), Laravel 的預設 convention 使用id尋找對應 model
 可在 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 分鐘內可存取次數的上限
# Distanct 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
# Additional
以下的 Laravel example code 的意思是?
- Example:<?php
 Route::middleware(['throttle:uploads'])->group(function () {
 Route::post('/audio', function () {
 //
 });
 Route::post('/video', function () {
 //
 });
 });
- Answer:
 attached 在 RouteServiceProvider 定義完成的 rate limiter 到指定的 route group
以下的 Laravel example code 的意思是?
- Example:<?php
 RateLimiter::for('login', function (Request $request) {
 return [
 Limit::perMinute(500),
 Limit::perMinute(3)->by($request->input('email')),
 ];
 });
- Answer:
 使用 configureRateLimiting() 來定義多個 rate limiter, throttle 每分鐘次數, 每分鐘可 500 次, 但同個 mail 每分鐘最多 3 次
以下的 Laravel example code 的意思是?
- Example:<?php
 // RouteServiceProvider
 RateLimiter::for('uploads', function (Request $request) {
 return $request->user()
 ? Limit::perMinute(100)->by($request->user()->id)
 : Limit::perMinute(10)->by($request->ip());
 });
- Answer:
 使用 configureRateLimiting() 來定義一個 rate limiter, throttle 每分鐘次數, authenticated user 每分鐘 100 次, guest per ip 每分鐘 10 次
以下的 Laravel example code 的意思是?
- Example:<?php
 // RouteServiceProvider
 RateLimiter::for('uploads', function (Request $request) {
 return $request->user()->vipCustomer()
 ? Limit::none()
 : Limit::perMinute(100)->by($request->ip());
 });
- Answer:
 使用 configureRateLimiting() 來定義一個 rate limiter, throttle 每分鐘次數, 如果 user 是 vip, 就無限制, 否則每分鐘,每 IP100 次
以下的 Laravel example code 的意思是?
- Example:<?php
 // RouteServiceProvider
 RateLimiter::for('uploads', function (Request $request) {
 return $request->user()->vipCustomer()
 ? Limit::none()
 : Limit::perMinute(100);
 });
- Answer:
 使用 configureRateLimiting() 來定義一個 rate limiter, throttle 每分鐘次數, 如果 user 是 vip, 就無限制, 否則每分鐘 100 次
以下的 Laravel example code 的意思是?
- Example:<?php
 // RouteServiceProvider
 RateLimiter::for('global', function (Request $request) {
 return Limit::perMinute(1000)->response(function () {
 return response('Custom response...', 429);
 });
 });
- Answer:
 使用 configureRateLimiting() 來定義一個 rate limiter, throttle 每分鐘次數, 並定義 response
以下的 Laravel example code 的意思是?
- Example:<?php
 // RouteServiceProvider
 protected function configureRateLimiting()
 {
 RateLimiter::for('global', function (Request $request) {
 return Limit::perMinute(1000);
 });
 }
- Answer:
 使用 configureRateLimiting() 來定義一個 rate limiter, throttle 每分鐘次數
留言