【一點點 Laravel 】HTTP Request (1) 原來 HTTP Requests 是這麼一回事!

WenChiYeh
7 min readOct 13, 2021

--

轉職後開始接觸 Laravel 的時間有半年了,工作上的使用沒有太大的問題,但我卻對 Laravel 的原理、以及一些好用的框架內建工具似懂非懂,覺得是時候好好地深入了解、打通任督二脈了。舉例來說, Validation 在處理資料上一定會使用到,但我卻是在前輩的提點下才發現,原來 Validation 的 Rule 可以自行打造、制定規則,對於初接觸後端框架半年的我來說,這真的是太酷了!

因此,接下來想寫的 「一點點 Laravel 」系列,是想模仿 iThome 鐵人賽,每週詳讀官網上的一到兩個主題,以 Laravel 8.x 版本為主,每天(或每兩三天 XD)寫一點點,由淺入深,複習淺的、學習深的,好好的熟練這個框架。

另外補充說明一下, Laravel 的官方文件寫得很好也很詳盡,能夠熟讀網站的內容,其實應該就能掌握很多東西了!非常建議閱讀英文版的網站,因為中文版的網站除了提供的版本較舊之外,有些東西似乎也沒寫得那麼仔細。

第一個想深入研讀的主題是 HTTP Requests 。說來汗顏,Requests 工作上用得頻繁,但會用歸會用,卻從來沒有深度去探索過它。

● Laravel 是怎麼處理 HTTP requests 的?
Laravel 提供了 Illuminate\Http\Request 這個 class ,透過這個 class ,後端可以取得資料、cookies、檔案等從請求送過來的資訊。

● 如何在 Laravel 中獲取 HTTP requests 的實例?
官網中是這麼寫的,「To obtain an instance of the current HTTP request via dependency injection, you should type-hint the Illuminate\Http\Request class on your route closure or controller method.」。

「type-hint」這個沒看過的詞語出現了!既然要深入的研讀官網,那就盡可能地把所有不認識、不了解的細節,都來一併查清楚。根據網路上查到過去他人的分享,「type-hint」在剛於 PHP 5 的版本出現是用來指定 function arguments 或 return values 的型別,且限定指定型別只能是 class 及 interface名稱、array 和 callable。

在 PHP 官網的最新文件中,已經沒有使用 「type-hint」這個詞語了,但仍有這樣的概念,能夠指定 function arguments 、return values,或是 class properties 的型別,叫「type declarations」。咦!閱讀到這裡,發現我自己在平常工作時,其實很常用到 「type declarations」,用以限制參數和回傳值的型別,讓資料型別更嚴謹也減少出錯,只是不知道這叫「type declarations」罷了。實際上「type declarations」可以指定哪些型別可以參考 PHP 官方文件:https://www.php.net/manual/en/language.types.declarations.php

回歸正題,所以官方文件想要說明的只有一件事,就是當你想要在函式中取用 HTTP Request 的實例,請在參數中指定注入 Request 這個物件。

官網範例如下,在 Controller 的 function 中做使用:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
/**
* Store a new user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$name = $request->input('name');

//
}
}

這邊也有提到,Request 實例是由 Service Container 注入,但由於這個概念比較難,且若這個書寫計畫會繼續下去的話,之後應該是碰得到,這邊就先跳過了~

此外,Request 的實例也可以直接注入 Route 的 closure,但由於我自己覺得直接在 Route 使用 closure 應該不會是大型專案常用的作法,所以就不深入探討這塊了!

● 取得路由參數
這個主題突然出現在這,也是稍微突兀。不過既然官網寫了,就一併閱讀。要在 Controller 中取得路由參數,可以在參數部分注入 Request Instance 後注入,這個方法在處理編輯某一筆資料時,很常會使用到。

在路由檔案中這樣做:

use App\Http\Controllers\UserController;

Route::put('/user/{id}', [UserController::class, 'update']);

在 Controller 檔案中這樣做:

public function update(Request $request, $id)
{
//
}

● 從 HTTP Request 的 Instance 還可以取到什麼呢?
Illuminate\Http\Request 這個 class 提供了不少方法,官網列舉一些常見的,一起來看看吧!這邊先跳過一些真的看起來很冷門的,以及太過讀不懂的。

1/ Path : 提供請求的路徑,會返回主要 domain 後的路徑。若有要把這個路徑當作一些回傳路徑之類的,這個方法算滿方便的~

$uri = $request->path();

2/ Request URL:返回完整的 URL 有 urlfullUrl 這兩個方法,他們的差別在於 url 這個方法不會包含 query string ,fullUrl 會則會。使用上如同 Path,只是把方法替換一下就可以直接取得你要的資訊了。

3/ Request Method:要從 HTTP Request 取得請求方法的字串,簡單使用 method 即可;另一個很常用到的是 isMethod ,如果使用同一個路徑、不同方法做請求,就會判斷當下是用哪個方法進行請求的,以接續進行不同的處理,使用上也非常簡單,如同官網範例:

if ($request->isMethod('post')) {
//
}

4/ Header :Laravel 提供了 headerhasHeader 方法,可以視需求使用。

5/ IP:取得發出請求的 IP ,使用 ip 這個方法就可以囉!一樣方便又簡單~

6/ Content Type 檢驗: Laravel 提供了幾個檢驗 Request Content Type 的方法。使用 getAcceptableContentTypes 方法會得到一個返回陣列,陣列內容是列出所有這個 Request 接受的 Content Type;accepts 方法則可限定接受的 Content Type,若接受的 Content Type 有包含在此方法傳入的陣列中,會返回 true 值,官網用法如下:

if ($request->accepts(['text/html', 'application/json'])) {
// ...
}

寫著寫著也寫了不少,第一篇就到這裡吧(自行隨意決定斷點),下一篇來好好讀讀 Input 。雖然整篇寫下來,有一點點像在拿著官網上的東西照本宣科,不過也是有加入自己的一點點經驗後進行融會貫通。另外,在閱讀 HTTP Request 的文件時,嚴重的感到自己對網路領域的不熟,之後再找機會補足這些知識點~

參考文件:
Laravel 官網 — HTTP Requests:https://laravel.com/docs/8.x/requests
PHP 官網—Type Declarations:https://www.php.net/manual/en/language.types.declarations.php
逐步提昇PHP技術能力 — PHP的語言特性 : 型別 / Type Juggling / Type Hint :https://ithelp.ithome.com.tw/articles/10135041

--

--

WenChiYeh

轉職軟體工程師 | 斜槓職涯探索 | 行銷公關 | 語言學習