HTTP 請求
取得請求
要透過依賴注入的方式取得 HTTP 請求的實例,你必須在控制器的建構函子或方法中,使用 Illuminate\Http\Request
型別提示。當前的請求實例就會自動由服務容器注入:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class UserController extends Controller
{
/**
* 儲存新的使用者。
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$name = $request->input('name');
//
}
}
如果你的控制器方法也有從路由參數傳入的輸入資料,只需要將路由參數置於其他依賴之後。舉例來說,如果你的路由定義像是:
Route::put('user/{id}', 'UserController@update');
只要像下方一樣定義控制器方法,一樣可以使用 Illuminate\Http\Request
型別提示,同時取得你的路由參數 id
:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class UserController extends Controller
{
/**
* 更新指定的使用者。
*
* @param Request $request
* @param int $id
* @return Response
*/
public function update(Request $request, $id)
{
//
}
}
基本請求資訊
Illuminate\Http\Request
的實例提供了多種方法,用於檢查應用程式的 HTTP 請求。Larevel 的 Illuminate\Http\Request
繼承了 Symfony\Component\HttpFoundation\Request
類別。下方是該類別的幾個有用的方法:
取得請求的 URI
path
方法會回傳請求的 URI。所以,如果接收到的請求目標是 http://domain.com/foo/bar
,那麼 path
方法就會回傳 foo/bar
:
$uri = $request->path();
is
方法可以驗證接收到的請求 URI 與給定的規則是否相匹配。使用此方法時你可以將 *
符號作為萬用字元:
if ($request->is('admin/*')) {
//
}
若要取得完整的網址,而不只有路徑資訊,你可以對請求實例使用 url
方法:
$url = $request->url();
取得請求的方法
method
方法會回傳當次請求的 HTTP 動詞。你也可以透過 isMethod
方法來驗證 HTTP 動詞和給定的字串是否互相匹配:
$method = $request->method();
if ($request->isMethod('post')) {
//
}
PSR-7 請求
PSR-7 標準制定的 HTTP 訊息介面包含了請求及回應。如果你想獲得一個 PSR-7 的請求實例,你必須先安裝幾個函式庫。Laravel 使用 Symfony 的 HTTP 訊息橋接元件,將原 Laravel 的請求及回應轉換至 PSR-7 所支援的實作:
composer require symfony/psr-http-message-bridge
composer require zendframework/zend-diactoros
只要你安裝完這些函式庫,你就可以在你的路由或控制器中,簡單的對請求類型使用型別提示取得 PSR-7 的請求:
use Psr\Http\Message\ServerRequestInterface;
Route::get('/', function (ServerRequestInterface $request) {
//
});
如果你從路由或控制器回傳一個 PSR-7 的回應實例,它會被框架自動轉換回 Laravel 的回應實例並顯示。
取得輸入資料
取得特定輸入值
你可以透過 Illuminate\Http\Request
的實例,經由幾個簡潔的方法取得所有的使用者輸入資料。不需要擔心發出請求時使用的 HTTP 動詞,取得輸入資料的方式都是相同的。
$name = $request->input('name');
此外,你可以使用 Illuminate\Http\Request
的屬性存取使用者輸入。例如,如果你應用程式的表單含有一個 name
欄位,你可以從傳遞的欄位存取它的值,像這樣:
$name = $request->name;
你可以在 input
方法的第二個參數傳入一個預設值。當請求的輸入資料不存在於當次請求,就會回傳預設值:
$name = $request->input('name', 'Sally');
如果是「陣列」形式的輸入資料,可以使用「點」語法取得陣列:
$input = $request->input('products.0.name');
確認是否有輸入值
要判斷資料是否存在於當次請求,你可以使用 has
方法。當該資料存在而且不為空字串時,has
方法就會傳回 true
:
if ($request->has('name')) {
//
}
取得所有輸入資料
你也可以使用 all
方法以陣列
形式取得所有輸入資料的:
$input = $request->all();
取得部分輸入資料
如果你想取得輸入資料的子集,你可以使用 only
及 except
方法。這兩個方法都接受單一陣列
或是動態列表作為參數:
$input = $request->only(['username', 'password']);
$input = $request->only('username', 'password');
$input = $request->except(['credit_card']);
$input = $request->except('credit_card');
舊輸入資料
Laravel 可以讓你保留這次的輸入資料,直到下一次請求發送前。對於在表單驗證失敗後重新填入表單值相當有用。當然,如果你使用 Laravel 的驗證服務,你就不需要手動使用這些方法,因為一些 Laravel 內建的驗證功能會自動呼叫它們。
將輸入資料快閃至 Session
Illuminate\Http\Request
實例的 flash
方法會將當前的輸入資料存進 Session 中,所以下次使用者發出請求至應用程式時就可以使用它們:
$request->flash();
你也可以使用 flashOnly
及 flashExcept
方法將請求資料的子集儲存至 Session:
$request->flashOnly('username', 'email');
$request->flashExcept('password');
快閃輸入資料至 Session 後重導
你可能常常想要將輸入資料快閃並重導至前一頁,你只要在重導方法後串接 withInput
就行了:
return redirect('form')->withInput();
return redirect('form')->withInput($request->except('password'));
取得舊輸入資料
若要取得前次請求所快閃的輸入資料,你可以使用 Request
實例中的 old
方法。old
方法提供一個簡便的方式從 Session 取出被快閃的輸入資料:
$username = $request->old('username');
Laravel 也提供了全域輔助方法 old
。如果你要在 Blade 模板顯示舊輸入資料,可以使用更加方便的輔助方法 old
:
{{ old('username') }}
Cookies
從請求取的 Cookie 值
Laravel 框架建立的每個 cookie 會加密並且加上認證記號,這代表著被使用者擅自更改的 cookie 會失效。若要從當次請求取得 cookie 值,你可以使用 Illuminate\Http\Request
實例中的 cookie
方法:
$value = $request->cookie('name');
加上新的 Cookie 至回應
Laravel 提供了全域輔助方法 cookie
,透過簡易的工廠來產生新的 Symfony\Component\HttpFoundation\Cookie
實例。可以在 Illuminate\Http\Response
實例之後連接 withCookie
方法帶入 cookie 至回應:
$response = new Illuminate\Http\Response('Hello World');
$response->withCookie(cookie('name', 'value', $minutes));
return $response;
如果要建立一個長期存在,為期五年的 cookie,你可以先呼叫 cookie
輔助方法且不帶入任何參數,再使用 cookie 工廠的 forever
方法,接著將 forever
方法串接在回傳的 cookie 工廠:
$response->withCookie(cookie()->forever('name', 'value'));
上傳檔案
取得上傳檔案
你可以使用 Illuminate\Http\Request
實例中的 file
方法取得上傳的檔案。file 方法回傳的物件是 Symfony\Component\HttpFoundation\File\UploadedFile
類別的實例,該類別繼承了 PHP 的 SplFileInfo
類別並提供了許多和檔案互動的方法:
$file = $request->file('photo');
確認檔案是否有上傳
你可以使用請求的 hasFile
方法確定上傳的檔案是否存在:
if ($request->hasFile('photo')) {
//
}
確認上傳的檔案是否有效
除了檢查上傳的檔案是否存在外,你也可以透過 isValid
方法驗證上傳的檔案是否有效:
if ($request->file('photo')->isValid()) {
//
}
移動上傳的檔案
若要移動上傳的檔案至新的位置,你必須使用 move
方法。該方法會將檔案從暫存位置(由你的 PHP 設定來決定)移動至你指定的永久保存位置:
$request->file('photo')->move($destinationPath);
$request->file('photo')->move($destinationPath, $fileName);
其他上傳檔案的方法
UploadedFile
的實例還有許多可用的方法,可以至該物件的 API 文件瞭解有關這些方法的詳細資訊。