翻譯進度
45.79% 已翻譯
更新時間:
2024年6月30日 上午8:27:00 [世界標準時間]
翻譯人員:
幫我們翻譯此頁

HTTP Request

簡介

Laravel 的 Illuminate\Http\Request 類別提供了一種物件導向的方法來讓你存取目前程式在處理的 HTTP Request,包含 Request 的輸入、Cookie、上傳的檔案⋯⋯等。

使用 Request

Accessing the Request

若要通過相依性插入 (Dependency Injection) 來取得目前的 HTTP Request,可在 Route 閉包或 Controller 方法上型別提示 Illuminate\Http\Request 類別。連入的 Request 實體會自動被插入到 Laravel 的 Service Container

1<?php
2 
3namespace App\Http\Controllers;
4 
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7 
8class UserController extends Controller
9{
10 /**
11 * Store a new user.
12 */
13 public function store(Request $request): RedirectResponse
14 {
15 $name = $request->input('name');
16 
17 // Store the user...
18 
19 return redirect('/users');
20 }
21}
1<?php
2 
3namespace App\Http\Controllers;
4 
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7 
8class UserController extends Controller
9{
10 /**
11 * Store a new user.
12 */
13 public function store(Request $request): RedirectResponse
14 {
15 $name = $request->input('name');
16 
17 // Store the user...
18 
19 return redirect('/users');
20 }
21}

剛才也提到過,我們也可以在 Route 閉包上型別提示 Illuminate\Http\Request 類別。Service Container 會自動在閉包執行時將連入的 Request 插入進去:

1use Illuminate\Http\Request;
2 
3Route::get('/', function (Request $request) {
4 // ...
5});
1use Illuminate\Http\Request;
2 
3Route::get('/', function (Request $request) {
4 // ...
5});

Dependency Injection and Route Parameters

若 Controller 方法中還會從 Route 引數中收到輸入,請將 Route 引數列在其他相依性之後。舉例來說,若 Route 定義長這樣:

1use App\Http\Controllers\UserController;
2 
3Route::put('/user/{id}', [UserController::class, 'update']);
1use App\Http\Controllers\UserController;
2 
3Route::put('/user/{id}', [UserController::class, 'update']);

則我們還是可以像這樣定義 Controller 方法來型別提示 Illuminate\Http\Request 並取得 id Route 參數:

1<?php
2 
3namespace App\Http\Controllers;
4 
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7 
8class UserController extends Controller
9{
10 /**
11 * Update the specified user.
12 */
13 public function update(Request $request, string $id): RedirectResponse
14 {
15 // Update the user...
16 
17 return redirect('/users');
18 }
19}
1<?php
2 
3namespace App\Http\Controllers;
4 
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7 
8class UserController extends Controller
9{
10 /**
11 * Update the specified user.
12 */
13 public function update(Request $request, string $id): RedirectResponse
14 {
15 // Update the user...
16 
17 return redirect('/users');
18 }
19}

Request Path, Host, and Method

Illuminate\Http\Request 提供了多種可檢查連入 HTTP Request 的方法。這個方法也繼承了 Symfony\Component\HttpFoundation\Request 類別。我們稍後會討論其中幾個最重要的方法。

Retrieving the Request Path

path 方法會回傳 Request 的路徑資訊。因此,若連入 Request 是在瀏覽 http://example.com/foo/bar,則 path 方法會回傳 foo/bar

1$uri = $request->path();
1$uri = $request->path();

Inspecting the Request Path / Route

可以使用 is 方法來驗證連入 Request 的路徑是否符合給定的格式。使用這個方法的時候,可以使用 * 字元作為萬用字元:

1if ($request->is('admin/*')) {
2 // ...
3}
1if ($request->is('admin/*')) {
2 // ...
3}

使用 routeIs 方法可以判斷連入的 Request 是否為某個命名 Route

1if ($request->routeIs('admin.*')) {
2 // ...
3}
1if ($request->routeIs('admin.*')) {
2 // ...
3}

Retrieving the Request URL

若要取得連入 Request 的完整 URL,可以使用 urlfullUrl 方法。url 方法會回傳不含查詢字串 (Query String) 的 URL,而 fullUrl 則包含查詢字串:

1$url = $request->url();
2 
3$urlWithQueryString = $request->fullUrl();
1$url = $request->url();
2 
3$urlWithQueryString = $request->fullUrl();

若想將查詢字串資料附加到目前的 URL,可以使用 fullUrlWithQuery 方法。傳入一個包含查詢字串變數的陣列,然後這個方法會將給定的陣列與目前的查詢字串合併:

1$request->fullUrlWithQuery(['type' => 'phone']);
1$request->fullUrlWithQuery(['type' => 'phone']);

若想取得不含給定 Query String 參數的目前 URL,可使用 fullUrlWithoutQuery 方法:

1$request->fullUrlWithoutQuery(['type']);
1$request->fullUrlWithoutQuery(['type']);

Retrieving the Request Host

可以使用 hosthttpHost、與 schemeAndHttpHost 來取得連入 Request 的「主機」:

1$request->host();
2$request->httpHost();
3$request->schemeAndHttpHost();
1$request->host();
2$request->httpHost();
3$request->schemeAndHttpHost();

Retrieving the Request Method

method 方法會回傳該 Request 的 HTTP 動詞 (Verb)。可以使用 isMethod 方法來判斷目前的 HTTP 動詞是否符合給定字串:

1$method = $request->method();
2 
3if ($request->isMethod('post')) {
4 // ...
5}
1$method = $request->method();
2 
3if ($request->isMethod('post')) {
4 // ...
5}

Request 標頭

可以使用 header 方法來從 Illuminate\Http\Request 內取得 Request 的標頭 (Header)。若該 Request 未包含指定的標頭,則會回傳 null。不過,header 方法也接受第三個可選的引數,會在標頭不存在時回傳該值:

1$value = $request->header('X-Header-Name');
2 
3$value = $request->header('X-Header-Name', 'default');
1$value = $request->header('X-Header-Name');
2 
3$value = $request->header('X-Header-Name', 'default');

hasHeader 方法可用來判斷 Request 是否包含給定的標頭:

1if ($request->hasHeader('X-Header-Name')) {
2 // ...
3}
1if ($request->hasHeader('X-Header-Name')) {
2 // ...
3}

為了方便起見,可以使用 bearerToken 方法來從 Authorization 標頭中取得 Bearer Token。若該標頭不存在,會回傳空字串:

1$token = $request->bearerToken();
1$token = $request->bearerToken();

Request 的 IP 位址

可以使用 ip 方法來取得用戶端發起 Request 使用的 IP 位址:

1$ipAddress = $request->ip();
1$ipAddress = $request->ip();

If you would like to retrieve an array of IP addresses, including all of the client IP addesses that were forwarded by proxies, you may use the ips method. The "original" client IP address will be at the end of the array:

1$ipAddresses = $request->ips();
1$ipAddresses = $request->ips();

In general, IP addresses should be considered untrusted, user-controlled input and be used for informational purposes only.

判斷適當的內容

Laravel 提供了數種方法來通過 Accept 標頭判斷連入 Request 所要求的 Content Type (內容類型)。首先,getAcceptableContentTypes 會回傳一個陣列,其中包含該 Request 所接受的所有 Content Type:

1$contentTypes = $request->getAcceptableContentTypes();
1$contentTypes = $request->getAcceptableContentTypes();

accepts 方法接受一個包含 Content Type 的陣列,當陣列中有任何一個 Content Type 是 Request 接受的,就會回傳 true。否則,會回傳 false

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

可以使用 prefers 方法來判斷給定陣列中的哪個 Content Type 是該 Request 最優先選擇的。若所提供的 Content Type 都不為 Request 接受,則會回傳 null

1$preferred = $request->prefers(['text/html', 'application/json']);
1$preferred = $request->prefers(['text/html', 'application/json']);

因為大部分專案都只提供 HTML 或 JSON,所以我們可以通過 expectsJson 方法來快速判斷連入的 Request 是否預期 Response 應為 JSON:

1if ($request->expectsJson()) {
2 // ...
3}
1if ($request->expectsJson()) {
2 // ...
3}

PSR-7 Request

PSR-7 標準 指定了用於 HTTP 訊息通訊的介面,其中包含 Request 與 Response。若你想取得 PSR-7 Request 的實體而不是 Laravel Request,首先你會需要安裝幾個函式庫。Laravel 使用 Symfony 的 HTTP Message Bridge 元件來將一般的 Laravel Request 與 Response 轉換為相容於 PSR-7 的實作:

1composer require symfony/psr-http-message-bridge
2composer require nyholm/psr7
1composer require symfony/psr-http-message-bridge
2composer require nyholm/psr7

安裝好這些函式庫後,就可以在 Route 閉包或 Controller 方法上型別提示 PSR-7 Request 介面來取得 PSR-7 Request 的實體:

1use Psr\Http\Message\ServerRequestInterface;
2 
3Route::get('/', function (ServerRequestInterface $request) {
4 // ...
5});
1use Psr\Http\Message\ServerRequestInterface;
2 
3Route::get('/', function (ServerRequestInterface $request) {
4 // ...
5});
lightbulb

若從 Route 或 Controller 中回傳 PSR-7 Response,這個 Response 會先被轉回到 Laravel 的 Response 實體,然後才會由 Laravel 顯示出來。

輸入

取得輸入

取得所有輸入的資料

可以使用 all 方法來將所有連入 Request 的輸入資料取得為 array。無論連入的 Request 是來自 HTML 表單還是 XHR Request,都可以使用這個方法:

1$input = $request->all();
1$input = $request->all();

使用 collect 方法就可以將連入 Request 的輸入資料作為 Collection 取得:

1$input = $request->collect();
1$input = $request->collect();

使用 collect 方法也可以用來將連入 Request 輸入中的一部分取得為 Collection:

1$request->collect('users')->each(function (string $user) {
2 // ...
3});
1$request->collect('users')->each(function (string $user) {
2 // ...
3});

Retrieving an Input Value

使用幾個簡單的方法,不需要擔心 Request 使用了哪個 HTTP 動詞,都可以存取 Illuminate\Http\Request 實體中所有的使用者輸入。無論 HTTP 動詞是什麼,都可以用 input 方法來取得使用者輸入:

1$name = $request->input('name');
1$name = $request->input('name');

也可以傳入第二個引數給 input 方法來取得預設值。若 Request 中沒有要求的輸入值時,就會回傳這個預設值:

1$name = $request->input('name', 'Sally');
1$name = $request->input('name', 'Sally');

在處理包含陣列輸入的表單時,可以使用「點 (.)」標記法來存取陣列:

1$name = $request->input('products.0.name');
2 
3$names = $request->input('products.*.name');
1$name = $request->input('products.0.name');
2 
3$names = $request->input('products.*.name');

呼叫 input 方法時若不傳入任何引數,則可以用關聯式陣列的方式取得所有輸入資料:

1$input = $request->input();
1$input = $request->input();

Retrieving Input From the Query String

雖然 input 方法可以從所有的 Request 承載 (Payload) 上取得資料 (其中也包含查詢字串),若使用 query 方法,則可以只從查詢字串中取得資料:

1$name = $request->query('name');
1$name = $request->query('name');

若要求的查詢字串值不存在,則會回傳第二個傳入該方法的值:

1$name = $request->query('name', 'Helen');
1$name = $request->query('name', 'Helen');

呼叫 query 方法時若不傳入任何引數,則可以用關聯式陣列的方式取得所有查詢字串的資料:

1$query = $request->query();
1$query = $request->query();

取得 JSON 輸入值

傳送 JSON 的 Request 時,只要 Request 的 Content-Type 由正確設定為 application/json,就可以使用 input 方法來存取 JSON 資料。也可以使用「點 (.)」標記法來存取 JSON 陣列/物件中的巢狀資料:

1$name = $request->input('user.name');
1$name = $request->input('user.name');

取得 Stringable 的輸入值

除了將輸入值以原生型別的 string 取得,還可以使用 string 方法來將 Request 資料以 Illuminate\Support\Stringable 實體的形式取得:

1$name = $request->string('name')->trim();
1$name = $request->string('name')->trim();

取得布林輸入值

在處理如勾選框 (Checkbox) 等 HTML 元素時,我們的程式可能會收到以字串形式呈現的「真假」值。舉例來說,這個值可能是「true」或「on」。為了方便起見,我們可以使用 boolean 方法來將這些值以布林方式取得。值為 1、"1"、true、"true"、"on"、"yes" 時,boolean 方法回傳 true。其他任何的值則會回傳 false

1$archived = $request->boolean('archived');
1$archived = $request->boolean('archived');

取得日期的輸入值

為了方便起見,我們可以使用 date 方法來將包含日期 / 時間的輸入值以 Carbon 實體來存取。若 Request 中為包含給定名稱的輸入值,則會回傳 null

1$birthday = $request->date('birthday');
1$birthday = $request->date('birthday');

可以使用 date 的第二與第三個引數來分別指定日期的格式與時區:

1$elapsed = $request->date('elapsed', '!H:i', 'Europe/Madrid');
1$elapsed = $request->date('elapsed', '!H:i', 'Europe/Madrid');

若輸入中有值,但格式不正確時,會擲回 InvalidArgumentException。因此,建議你在叫用 date 方法前先驗證輸入。

取得 Enum 輸入值

也可以從 Request 中取得對應到 PHP Enum 的輸入值。若 Request 中沒有輸入值,或是給定的名稱或 Enum 中沒有符合該輸入值的後端值 (Backing Value),則會回傳 nullenum 方法的第一個引數為輸入值的名稱、第二個引數為 Enum 類別:

1use App\Enums\Status;
2 
3$status = $request->enum('status', Status::class);
1use App\Enums\Status;
2 
3$status = $request->enum('status', Status::class);

Retrieving Input via Dynamic Properties

可以在 Illuminate\Http\Request 實體上通過動態屬性來存取使用者輸入。舉例來說,若其中一個程式的表單包含了 name 欄位,則可以像這樣存取該欄位的值:

1$name = $request->name;
1$name = $request->name;

使用動態方法時,Laravel 會先在 Request 的 Payload (承載) 上尋找參數值。若 Payload 上沒有該值,Laravel 會接著在 Route 參數中尋找符合名稱的欄位:

Retrieving a Portion of the Input Data

若只想取得一部分的輸入資料,可以使用 onlyexcept 方法。這兩個方法都接受一個 array 值、或是一組引數的動態列表:

1$input = $request->only(['username', 'password']);
2 
3$input = $request->only('username', 'password');
4 
5$input = $request->except(['credit_card']);
6 
7$input = $request->except('credit_card');
1$input = $request->only(['username', 'password']);
2 
3$input = $request->only('username', 'password');
4 
5$input = $request->except(['credit_card']);
6 
7$input = $request->except('credit_card');
lightbulb

only 方法會回傳所要求的所有索引鍵 / 值配對組。不過,若要求的索引鍵 / 值配對未出現在 Request 中,將不會回傳。

Input Presence

可以使用 has 方法來判斷某個值是否存在 Request 中。若給定的輸入值存在於 Request 中,has 方法會回傳 true

1if ($request->has('name')) {
2 // ...
3}
1if ($request->has('name')) {
2 // ...
3}

傳入陣列時,has 方法判斷其中所有的值是否都存在:

1if ($request->has(['name', 'email'])) {
2 // ...
3}
1if ($request->has(['name', 'email'])) {
2 // ...
3}

hasAny 方法會給定的值有其中一個存在時回傳 true

1if ($request->hasAny(['name', 'email'])) {
2 // ...
3}
1if ($request->hasAny(['name', 'email'])) {
2 // ...
3}

whenHas 方法會執行給定的閉包來判斷某個值是否存在於 Request 中:

1$request->whenHas('name', function (string $input) {
2 // ...
3});
1$request->whenHas('name', function (string $input) {
2 // ...
3});

可以傳入第二個閉包給 whenHas 方法,當指定的值未存在於 Request 中,則會執行這個閉包:

1$request->whenHas('name', function (string $input) {
2 // The "name" value is present...
3}, function () {
4 // The "name" value is not present...
5});
1$request->whenHas('name', function (string $input) {
2 // The "name" value is present...
3}, function () {
4 // The "name" value is not present...
5});

若想判斷某個值是否有出現在 Request 中,且該值不是空字串時,可使用 filled 方法:

1if ($request->filled('name')) {
2 // ...
3}
1if ($request->filled('name')) {
2 // ...
3}

anyFilled 方法會在給定的值中有其中一個值不為空字串時回傳 true

1if ($request->anyFilled(['name', 'email'])) {
2 // ...
3}
1if ($request->anyFilled(['name', 'email'])) {
2 // ...
3}

whenFilled 方法會執行給定的閉包來判斷 Request 中某個值是否為空字串:

1$request->whenFilled('name', function (string $input) {
2 // ...
3});
1$request->whenFilled('name', function (string $input) {
2 // ...
3});

可以傳入第二個閉包給 whenFilled 方法,當 Request 中指定的值為空時會執行這個閉包:

1$request->whenFilled('name', function (string $input) {
2 // The "name" value is filled...
3}, function () {
4 // The "name" value is not filled...
5});
1$request->whenFilled('name', function (string $input) {
2 // The "name" value is filled...
3}, function () {
4 // The "name" value is not filled...
5});

若要判斷 Request 中是否不存在給定的索引鍵,可使用 missing 方法與 whenMissing 方法:

1if ($request->missing('name')) {
2 // ...
3}
4 
5$request->whenMissing('name', function (array $input) {
6 // The "name" value is missing...
7}, function () {
8 // The "name" value is present...
9});
1if ($request->missing('name')) {
2 // ...
3}
4 
5$request->whenMissing('name', function (array $input) {
6 // The "name" value is missing...
7}, function () {
8 // The "name" value is present...
9});

合併額外的輸入

有時候,我們需要手動合併額外的輸入到 Request 中現有的輸入資料。這種情況下,可使用 merge 方法。若 Request 中已存在給定的輸入索引鍵,則會使用提供給 merge 方法的資料來複寫:

1$request->merge(['votes' => 0]);
1$request->merge(['votes' => 0]);

使用 mergeIfMissing 方法就可以只在 Request 的輸入資料中缺少特定索引鍵時才合併進 Request:

1$request->mergeIfMissing(['votes' => 0]);
1$request->mergeIfMissing(['votes' => 0]);

舊輸入

Laravel 提供了將輸入資料從一個 Request 帶到下一個 Request 的功能。這個功能特別適合用在表單驗證失敗後要重新填充表單時。不過,若你使用 Laravel 提供的表單驗證功能,那麼你應該不需要直接手動進行這些 Session 的 Input 快閃方法,因為 Laravel 的內建表單驗證功能已經自動處理好了。

Flashing Input to the Session

使用 Illuminate\Http\Request 類別的 flash 方法,就可以將目前的輸入快閃 (Flash) 進 Session。這樣一來,使用者的下個 Request 中就有這些輸入值可用:

1$request->flash();
1$request->flash();

也可以使用 flashOnlyflashExcept 方法來只將一部分的 Request 資料刷入 Session。這些方法特別適用於想讓一些機密資料(如密碼)不要被刷入 Session 時:

1$request->flashOnly(['username', 'email']);
2 
3$request->flashExcept('password');
1$request->flashOnly(['username', 'email']);
2 
3$request->flashExcept('password');

快閃存入輸入後再重新導向

由於我們很常會需要再將輸入資料快閃存入 Session 後再重新導向回上一頁,因此我們只要把 withInput 方法串到重新導向後,就可以輕鬆地快閃存入輸入值:

1return redirect('form')->withInput();
2 
3return redirect()->route('user.create')->withInput();
4 
5return redirect('form')->withInput(
6 $request->except('password')
7);
1return redirect('form')->withInput();
2 
3return redirect()->route('user.create')->withInput();
4 
5return redirect('form')->withInput(
6 $request->except('password')
7);

取得舊輸入

若要取得前一個 Request 中的快閃輸入,可叫用 Illuminate\Http\Request 上的 old 方法。old 方法從 Session 中拉取前次快閃存入輸入資料:

1$username = $request->old('username');
1$username = $request->old('username');

Laravel 也提供了一個全域 old 輔助函式。若想在 Blade 樣板中顯示舊輸入,那麼使用 old 輔助函式來將其填回表單回比較方便。若給定欄位沒有舊輸入的話,會回傳 null

1<input type="text" name="username" value="{{ old('username') }}">
1<input type="text" name="username" value="{{ old('username') }}">

Cookie

從 Request 中取得 Cookie

所有由 Laravel 框架所建立的 Cookie 都是經過加密且使用驗證碼簽名過的,這代表若用戶端有修改這些值,就會讓 Cookie 變成無效。若要從 Request 中取得 Cookie,請使用 Illuminate\Http\Request 實體上的 cookie 方法:

1$value = $request->cookie('name');
1$value = $request->cookie('name');

Input Trimming and Normalization

預設情況下,Laravel 中包含了 App\Http\Middleware\TrimStringsIlluminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull 這兩個 Middleware,且放在程式的全域 Middleware Stack 中。這些 Middleware 被列在 App\Http\Kernel 類別的全域 Middleware Stack 中。這些 Middleware 會自動修剪 Request 中的所有連入子船,並將空白的字串欄位轉為 null。這樣,我們就不需要在 Route 或 Controller 中去費心正常化這些資料。

禁用輸入正規化

若想在所有 Request 上禁用這些行為,可在 App\Http\Kernel 類別的 $middleware 屬性中將其移除:

若只想在專案中一部分的 Request 上禁用字串修剪與空字串轉換,可使用這兩個 Middleware 提供的 skipWhen 方法。請傳入一個回傳 truefalse 的閉包給該方法,用來判斷是否應跳過字串的正規化。一般來說,應在專案的 AppServiceProviderboot 方法內叫用這個 skipWhen 方法。

1use App\Http\Middleware\TrimStrings;
2use Illuminate\Http\Request;
3use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
4 
5/**
6 * Bootstrap any application services.
7 */
8public function boot(): void
9{
10 TrimStrings::skipWhen(function (Request $request) {
11 return $request->is('admin/*');
12 });
13 
14 ConvertEmptyStringsToNull::skipWhen(function (Request $request) {
15 // ...
16 });
17}
1use App\Http\Middleware\TrimStrings;
2use Illuminate\Http\Request;
3use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
4 
5/**
6 * Bootstrap any application services.
7 */
8public function boot(): void
9{
10 TrimStrings::skipWhen(function (Request $request) {
11 return $request->is('admin/*');
12 });
13 
14 ConvertEmptyStringsToNull::skipWhen(function (Request $request) {
15 // ...
16 });
17}

檔案

取得上傳的檔案

可以使用 file 方法或動態屬性來從 Illuminate\Http\Request 實體上取得上傳的檔案。file 方法會回傳 Illuminate\Http\UploadedFile 類別的實體,該實體繼承了 PHP 的 SplFileInfo 類別,並提供各種能處理使用該檔案的方法:

1$file = $request->file('photo');
2 
3$file = $request->photo;
1$file = $request->file('photo');
2 
3$file = $request->photo;

可以使用 hasFile 方法來判斷某個檔案是否存在於 Request 中:

1if ($request->hasFile('photo')) {
2 // ...
3}
1if ($request->hasFile('photo')) {
2 // ...
3}

驗證成功上傳

除了檢查檔案是否存在外,還可以使用 isValid 方法來確認上傳檔案的過程中是否無問題:

1if ($request->file('photo')->isValid()) {
2 // ...
3}
1if ($request->file('photo')->isValid()) {
2 // ...
3}

File Paths and Extensions

UploadedFile 類別也包含了能存取檔案完整路徑與副檔名的方法。extension 方法可以使用檔案的內容來推測檔案的副檔名。這個副檔名克呢功能會與用戶端提供的副檔名有所不同:

1$path = $request->photo->path();
2 
3$extension = $request->photo->extension();
1$path = $request->photo->path();
2 
3$extension = $request->photo->extension();

其他檔案方法

UploadedFile 實體還提供了其他各種方法。請參考該類別的 API 說明文件來瞭解有關這些方法的更多資訊。

儲存上傳的檔案

若要儲存已上傳的檔案,通常我們需要先設定好檔案系統UploadedFile 類別中有個 store 方法,該方法可以將已上傳的檔案移到其中一個磁碟裡。這個磁碟可以是本機檔案系統,也可以是像 Amazon S3 之類的雲端儲存空間。

store 方法接受一個路徑,該路徑就是相對於檔案系統設定中根目錄的位置。路徑不包含檔案名稱,Laravel 會自動產生獨立的 ID 來當作檔案名稱。

store 方法也接受可選的第二個引數,該引數是要用來儲存檔案的磁碟名稱。 store 方法會回傳相對於磁碟根目錄的檔案路徑:

1$path = $request->photo->store('images');
2 
3$path = $request->photo->store('images', 's3');
1$path = $request->photo->store('images');
2 
3$path = $request->photo->store('images', 's3');

若不想要自動產生的檔案名稱,可以使用 storeAs 方法,該方法的引數是路徑、檔案名稱、磁碟名稱:

1$path = $request->photo->storeAs('images', 'filename.jpg');
2 
3$path = $request->photo->storeAs('images', 'filename.jpg', 's3');
1$path = $request->photo->storeAs('images', 'filename.jpg');
2 
3$path = $request->photo->storeAs('images', 'filename.jpg', 's3');
lightbulb

更多有關 Laravel 中檔案儲存的資訊,請參考完整的檔案儲存說明文件

設定信任的代理 (Trusted Proxy)

在負責處理 TLS / SSL 證書的 Load Balancer (負載平衡器) 後方執行應用程式時,有時候由 url 輔助函式產生的連結可能不會使用 HTTPS。者通常是因為,Load Balancer 把流量傳過來時使用的是 80 Port,因為 Laravel 不知道是否要產生 HTTPS 的連結。

為此,我們可以使用 Laravel 專案中有包含的 App\Http\Middleware\TrustProxies Middleware。該 Middleware 能讓我們快速自訂程式要信任的 Load Balancer 或代理伺服器 (Proxy)。應在該 Middleware 內的 $proxies 屬性內列出信任的代理伺服器。除了設定信任的代理外,也可以設定信任代理的 $headers

1<?php
2 
3namespace App\Http\Middleware;
4 
5use Illuminate\Http\Middleware\TrustProxies as Middleware;
6use Illuminate\Http\Request;
7 
8class TrustProxies extends Middleware
9{
10 /**
11 * The trusted proxies for this application.
12 *
13 * @var string|array
14 */
15 protected $proxies = [
16 '192.168.1.1',
17 '192.168.1.2',
18 ];
19 
20 /**
21 * The headers that should be used to detect proxies.
22 *
23 * @var int
24 */
25 protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO;
26}
1<?php
2 
3namespace App\Http\Middleware;
4 
5use Illuminate\Http\Middleware\TrustProxies as Middleware;
6use Illuminate\Http\Request;
7 
8class TrustProxies extends Middleware
9{
10 /**
11 * The trusted proxies for this application.
12 *
13 * @var string|array
14 */
15 protected $proxies = [
16 '192.168.1.1',
17 '192.168.1.2',
18 ];
19 
20 /**
21 * The headers that should be used to detect proxies.
22 *
23 * @var int
24 */
25 protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO;
26}
lightbulb

若要使用 AWS Elastic Load Balancing,則 $headers 的值應為 Request::HEADER_X_FORWARDED_AWS_ELB。更多有關能用在 $headers 屬性的常數資訊,請參考 Symfony 說明文件中的 Trusting Proxies

信任所有代理

若使用 Amazon AWS 或其他的「雲端」Load Balancer 提供者,則我們可能不知道 Load Balancer 實際的 IP 位置。這時,可以使用 * 來信任所有代理:

1/**
2 * The trusted proxies for this application.
3 *
4 * @var string|array
5 */
6protected $proxies = '*';
1/**
2 * The trusted proxies for this application.
3 *
4 * @var string|array
5 */
6protected $proxies = '*';

設定信任的主機 (Trusted Hosts)

預設情況下,無論收到的 HTTP Request 中 Host 標頭內容為何,Laravel 都會回應所有收到的 Request。此外,Laravel 還會使用 Host 標頭的值來在 Request 中為你的程式產生絕對路徑的網址。

一般來說,應在 Web Server 上 (如 Nginx 或 Apache) 設定只有特定的主機名稱時才將 Request 送往你的程式中。不過,若沒機會能自訂 Web Server,則需要讓 Laravel 只對特定主機名稱作回應。為此,可以啟用專案中的 App\Http\Middleware\TrustHosts Middleware。

TrustHosts Middleware 以預先包含在專案中的 $middlware Stack 裡的。不過,需要先取消註解這個 Middleware,才能啟用它。在這個 Middleware 中有個 hosts 方法,我們可以在其中指定我們的程式要回應的主機名稱。有其他 Host 標頭值的連入 Request 將會被拒絕:

1/**
2 * Get the host patterns that should be trusted.
3 *
4 * @return array<int, string>
5 */
6public function hosts(): array
7{
8 return [
9 'laravel.test',
10 $this->allSubdomainsOfApplicationUrl(),
11 ];
12}
1/**
2 * Get the host patterns that should be trusted.
3 *
4 * @return array<int, string>
5 */
6public function hosts(): array
7{
8 return [
9 'laravel.test',
10 $this->allSubdomainsOfApplicationUrl(),
11 ];
12}

allSubdomainsOfApplicationUrl 輔助函式會回傳一個可配對應用程式中 app.url 設定值子網域的正規表示式。使用這個輔助函式,就可以方便地在使用萬用子網域的程式中允許所有的子網域。

翻譯進度
45.79% 已翻譯
更新時間:
2024年6月30日 上午8:27:00 [世界標準時間]
翻譯人員:
幫我們翻譯此頁

留言

尚無留言

“Laravel” is a Trademark of Taylor Otwell.
The source documentation is released under MIT license. See laravel/docs on GitHub for details.
The translated documentations are released under MIT license. See cornch/laravel-docs-l10n on GitHub for details.