翻譯進度
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 addresses 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 的輸入值

Instead of retrieving the request's input data as a primitive string, you may use the string method to retrieve the request data as an instance of Illuminate\Support\Stringable:

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

Retrieving Integer Input Values

To retrieve input values as integers, you may use the integer method. This method will attempt to cast the input value to an integer. If the input is not present or the cast fails, it will return the default value you specify. This is particularly useful for pagination or other numeric inputs:

1$perPage = $request->integer('per_page');
1$perPage = $request->integer('per_page');

取得布林輸入值

在處理如勾選框 (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);

If the input value is an array of values that correspond to a PHP enum, you may use the enums method to retrieve the array of values as enum instances:

1use App\Enums\Product;
2 
3$products = $request->enums('products', Product::class);
1use App\Enums\Product;
2 
3$products = $request->enums('products', Product::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}

If you would like to determine if a value is missing from the request or is an empty string, you may use the isNotFilled method:

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

When given an array, the isNotFilled method will determine if all of the specified values are missing or empty:

1if ($request->isNotFilled(['name', 'email'])) {
2 // ...
3}
1if ($request->isNotFilled(['name', 'email'])) {
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 () {
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 () {
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

By default, Laravel includes the Illuminate\Foundation\Http\Middleware\TrimStrings and Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull middleware in your application's global middleware stack. These middleware will automatically trim all incoming string fields on the request, as well as convert any empty string fields to null. This allows you to not have to worry about these normalization concerns in your routes and controllers.

禁用輸入正規化

If you would like to disable this behavior for all requests, you may remove the two middleware from your application's middleware stack by invoking the $middleware->remove method in your application's bootstrap/app.php file:

1use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
2use Illuminate\Foundation\Http\Middleware\TrimStrings;
3 
4->withMiddleware(function (Middleware $middleware) {
5 $middleware->remove([
6 ConvertEmptyStringsToNull::class,
7 TrimStrings::class,
8 ]);
9})
1use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
2use Illuminate\Foundation\Http\Middleware\TrimStrings;
3 
4->withMiddleware(function (Middleware $middleware) {
5 $middleware->remove([
6 ConvertEmptyStringsToNull::class,
7 TrimStrings::class,
8 ]);
9})

If you would like to disable string trimming and empty string conversion for a subset of requests to your application, you may use the trimStrings and convertEmptyStringsToNull middleware methods within your application's bootstrap/app.php file. Both methods accept an array of closures, which should return true or false to indicate whether input normalization should be skipped:

1->withMiddleware(function (Middleware $middleware) {
2 $middleware->convertEmptyStringsToNull(except: [
3 fn (Request $request) => $request->is('admin/*'),
4 ]);
5 
6 $middleware->trimStrings(except: [
7 fn (Request $request) => $request->is('admin/*'),
8 ]);
9})
1->withMiddleware(function (Middleware $middleware) {
2 $middleware->convertEmptyStringsToNull(except: [
3 fn (Request $request) => $request->is('admin/*'),
4 ]);
5 
6 $middleware->trimStrings(except: [
7 fn (Request $request) => $request->is('admin/*'),
8 ]);
9})

檔案

取得上傳的檔案

可以使用 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 的連結。

To solve this, you may enable the Illuminate\Http\Middleware\TrustProxies middleware that is included in your Laravel application, which allows you to quickly customize the load balancers or proxies that should be trusted by your application. Your trusted proxies should be specified using the trustProxies middleware method in your application's bootstrap/app.php file:

1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustProxies(at: [
3 '192.168.1.1',
4 '10.0.0.0/8',
5 ]);
6})
1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustProxies(at: [
3 '192.168.1.1',
4 '10.0.0.0/8',
5 ]);
6})

In addition to configuring the trusted proxies, you may also configure the proxy headers that should be trusted:

1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustProxies(headers: Request::HEADER_X_FORWARDED_FOR |
3 Request::HEADER_X_FORWARDED_HOST |
4 Request::HEADER_X_FORWARDED_PORT |
5 Request::HEADER_X_FORWARDED_PROTO |
6 Request::HEADER_X_FORWARDED_AWS_ELB
7 );
8})
1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustProxies(headers: Request::HEADER_X_FORWARDED_FOR |
3 Request::HEADER_X_FORWARDED_HOST |
4 Request::HEADER_X_FORWARDED_PORT |
5 Request::HEADER_X_FORWARDED_PROTO |
6 Request::HEADER_X_FORWARDED_AWS_ELB
7 );
8})
lightbulb

If you are using AWS Elastic Load Balancing, the headers value should be Request::HEADER_X_FORWARDED_AWS_ELB. If your load balancer uses the standard Forwarded header from RFC 7239, the headers value should be Request::HEADER_FORWARDED. For more information on the constants that may be used in the headers value, check out Symfony's documentation on trusting proxies.

信任所有代理

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

1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustProxies(at: '*');
3})
1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustProxies(at: '*');
3})

設定信任的主機 (Trusted Hosts)

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

Typically, you should configure your web server, such as Nginx or Apache, to only send requests to your application that match a given hostname. However, if you do not have the ability to customize your web server directly and need to instruct Laravel to only respond to certain hostnames, you may do so by enabling the Illuminate\Http\Middleware\TrustHosts middleware for your application.

To enable the TrustHosts middleware, you should invoke the trustHosts middleware method in your application's bootstrap/app.php file. Using the at argument of this method, you may specify the hostnames that your application should respond to. Incoming requests with other Host headers will be rejected:

1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustHosts(at: ['laravel.test']);
3})
1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustHosts(at: ['laravel.test']);
3})

By default, requests coming from subdomains of the application's URL are also automatically trusted. If you would like to disable this behavior, you may use the subdomains argument:

1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustHosts(at: ['laravel.test'], subdomains: false);
3})
1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustHosts(at: ['laravel.test'], subdomains: false);
3})

If you need to access your application's configuration files or database to determine your trusted hosts, you may provide a closure to the at argument:

1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustHosts(at: fn () => config('app.trusted_hosts'));
3})
1->withMiddleware(function (Middleware $middleware) {
2 $middleware->trustHosts(at: fn () => config('app.trusted_hosts'));
3})
翻譯進度
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.