訪問請求實例
要通過依賴注入獲取當前 HTTP 請求實例,需要在控制器的構造函數或方法中對 Illuminate\Http\Request
類進行類型提示,這樣當前請求實例會被服務容器自動注入:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
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;
class UserController extends Controller{
/**
* 更新指定用戶
*
* @param Request $request
* @param int $id
* @return Response
*/
public function update(Request $request,$id) {
//
}
}
通過路由閉包訪問請求
還可以在路由閉包上類型提示 Illuminate\Http\Request
類,在執行的時候服務容器會自動注入輸入的請求到閉包:
use Illuminate\Http\Request;
Route::get('/', function (Request $request) {
//
});
請求路徑 & 方法
Illuminate\Http\Request
實例提供了多個方法來檢測應用的 HTTP 請求,Laravel 的 Illuminate\Http\Request
繼承自 Symfony\Component\HttpFoundation\Request
類,下面演示了該類提供的一些有用方法:
獲取請求路徑
path
方法將會返回請求的路徑信息,因此,如果進入的請求路徑是 http://domain.com/foo/bar
,則 path
方法將會返回 foo/bar
:
$uri=$request->path();
is
方法允許你驗證進入的請求是否與給定模式匹配。使用該方法時可以使用 *
通配符:
if($request->is('admin/*')){
//
}
獲取請求URL
想要獲取完整的 URL
,而不僅僅是路徑信息,可以使用請求實例提供的 url
或 fullUrl
方法,url
方法將會返回不帶查詢字符串的 URL
,而 fullUrl
方法返回結果則包含查詢字符串:
// 不包含查詢字符串
$url = $request->url();
// 包含查詢字符串
$url = $request->fullUrl();
獲取請求方法
method
方法將會返回 HTTP 請求方式。你還可以使用 isMethod
方法來驗證 HTTP 請求方式是否匹配給定字符串:
$method=$request->method();if($request->isMethod('post')){ //}
PSR-7 請求
PSR-7 標準指定了 HTTP 消息接口,包括請求和響應。如果你想要獲取 PSR-7 請求實例,首先需要安裝一些庫,Laravel 使用 Symfony HTTP Message Bridge
組件將典型的 Laravel 請求和響應轉化為 兼容PSR-7
的實現:
composer require symfony/psr-http-message-bridgecomposer
require zendframework/zend-diactoros
安裝完這些庫之后,你只需要在路由或控制器中通過對請求類型進行類型提示就可以獲取PSR-7
請求:
use Psr\Http\Message\ServerRequestInterface;
Route::get('/', function (ServerRequestInterface $request) {
//
});
注:如果從路由或控制器返回的是
PSR-7
響應實例,則其將會自動轉化為 Laravel 響應實例并顯示出來。
輸入修整 & 正常化
默認情況下,Laravel 在 App\Http\Kernel
的全局中間件堆棧中引入了 TrimStrings
和 ConvertEmptyStringsToNull
中間件。這些中間件會自動對請求中的字符串字段進行處理,前者將字符串兩端的空格清除,后者將空字符串轉化為 null
。這樣,在路由和控制器中我們就不必對字符串字段做額外的處理。
如果你想要禁止該行為,可以從App\Http\Kernel
的中間件堆棧屬性 $middleware
中移除這兩個中間件。
獲取請求輸入
獲取所有輸入值
你可以使用 all
方法以數組格式獲取所有輸入值:
$input = $request->all();
獲取單個輸入值
使用一些簡單的方法,就可以從 Illuminate\Http\Request
實例中訪問用戶輸入。你不需要關心請求所使用的 HTTP
請求方法,因為對所有請求方式的輸入都是通過input
方法獲取用戶輸入:
$name = $request->input('name');
你還可以傳遞一個默認值作為第二個參數給 input
方法,如果請求輸入值在當前請求未出現時該值將會被返回:
$name = $request->input('name', 'Sally');
處理表單數組輸入時,可以使用”.”來訪問數組輸入:
$input = $request->input('products.0.name');
$names = $request->input('products.*.name');
通過動態屬性獲取輸入
此外,你還可以通過使用 Illuminate\Http\Request
實例上的動態屬性來訪問用戶輸入。例如,如果你的應用表單包含 name
字段,那么可以像這樣訪問提交的值:
$name = $request->name;
使用動態屬性的時候,Laravel 首先會在請求中查找參數的值,如果不存在,還會到路由參數中查找。
獲取JSON輸入值
發送JSON請求到應用的時候,只要 Content-Type
請求頭被設置為 application/json
,都可以通過input
方法獲取 JSON 數據,還可以通過“.”號解析數組:
$name = $request->input('user.name');
獲取輸入的部分數據
如果你需要取出輸入數據的子集,可以使用 only
或 except
方法,這兩個方法都接收一個數組或動態列表作為唯一參數:
$input = $request->only(['username', 'password']);
$input = $request->only('username', 'password');
$input = $request->except(['credit_card']);
$input = $request->except('credit_card');
only
方法返回你所請求的所有鍵值對,即使輸入請求中不包含你所請求的鍵,當對應鍵不存在時,對應返回值為 null
,如果你想要獲取輸入請求中確實存在的部分數據,可以使用 intersect
方法:
$input = $request->intersect(['username', 'password']);
判斷輸入值是否存在
判斷值是否在請求中存在,可以使用 has
方法,如果值出現過了且不為空,has
方法返回 true
:
if ($request->has('name')) {
//
}
上一次請求輸入
Laravel 允許你在兩次請求之間保存輸入數據,這個特性在檢測校驗數據失敗后需要重新填充表單數據時很有用,但如果你使用的是 Laravel 自帶的驗證服務,則不需要手動使用這些方法,因為一些 Laravel 自帶的校驗設置會自動調用它們。
將輸入存儲到一次性 Session
Illuminate\Http\Request
實例的 flash
方法會將當前輸入存放到一次性 Session(所謂的一次性指的是從 Session 中取出數據后,對應數據會從 Session 中銷毀)中,這樣在下一次請求時數據依然有效:
$request->flash();
你還可以使用 flashOnly
和 flashExcept
方法將輸入數據子集存放到 Session
中,這些方法在 Session
之外保存敏感信息時很有用:
$request->flashOnly('username', 'email');
$request->flashExcept('password');
將輸入存儲到一次性 Session 然后重定向
如果你經常需要一次性存儲輸入并重定向到前一頁,可以使用 withInput
方法來將輸入數據添加到 redirect
后面:
return redirect('form')->withInput();
return redirect('form')->withInput($request->except('password'));
取出上次請求數據
要從 Session
中取出上次請求的輸入數據,可以使用 Request 實例的 old
方法。old
方法可以很方便地從Session
中取出一次性數據:
$username = $request->old('username');
Laravel 還提供了一個全局的輔助函數 old
,如果你是在 Blade 模板中顯示上次輸入數據,使用輔助函數 old
更方便,如果給定參數沒有對應輸入,返回null
:
<input type="text" name="username" value="{{ old('username') }}">
文件上傳
獲取上傳的文件
可以使用 Illuminate\Http\Request
實例提供的 file
方法或者動態屬性來訪問上傳文件, file
方法返回Illuminate\Http\UploadedFile
類的一個實例,該類繼承自 PHP 標準庫中提供與文件交互方法的 SplFileInfo
類:
$file = $request->file('photo');$file = $request->photo;
你可以使用 hasFile
方法判斷文件在請求中是否存在:
if ($request->hasFile('photo')) {
//
}
驗證文件是否上傳成功
使用 isValid
方法判斷文件在上傳過程中是否出錯:
if ($request->file('photo')->isValid()){
//
}
文件路徑 & 擴展名
UploadedFile
類還提供了訪問上傳文件絕對路徑和擴展名的方法。 extension
方法可以基于文件內容判斷文件擴展名,該擴展名可能會和客戶端提供的擴展名不一致:
$path = $request->photo->path();
$extension = $request->photo->extension();
其他文件方法
UploadedFile
實例上還有很多其他可用方法,查看該類的API文檔了解更多信息。
保存上傳的文件
要保存上傳的文件,通常需要使用你所配置的其中一個文件系統, UploadedFile
類有一個 store
方法,該方法會將上傳文件移動到相應的磁盤路徑上,該路徑可以是本地文件系統的某個位置,也可以是云存儲(如Amazon S3)上的路徑。
store
方法接收一個文件保存的相對路徑(相對于文件系統配置的根目錄 ),該路徑不應該包含文件名,因為系統會自動生成一個唯一ID作為文件名。
store
方法還接收一個可選的參數——用于存儲文件的磁盤名稱作為第二個參數,該方法會方返回相對于根目錄的文件路徑:
$path = $request->photo->store('images');
$path = $request->photo->store('images', 's3');
如果你不想自動生成文件名,可以使用 storeAs
方法,該方法接收保存路徑、文件名和磁盤名作為參數:
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');