請求
請求
HTTP 請求
接受請求
要通過依賴注入獲取當(dāng)前 HTTP 請求實例,你應(yīng)該在控制器上引入 Illuminate\Http\Request
類, 傳入的請求實例將會由 服務(wù)容器 自動注入:
<?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'); // } }
依賴注入 & 路由參數(shù)
如果你的控制器需要從路由參數(shù)中獲取數(shù)據(jù),你應(yīng)該在其他依賴項之后列入?yún)?shù)。舉個例子,你的路由是這樣定義的:
Route::put('user/{id}', 'UserController@update');
你可以通過下面的方法來定義控制器,使用 Illuminate\Http\Request
類來獲取你的路由參數(shù) id
:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller{ /** * 更新指定用戶 * * @param Request $request * @param string $id * @return Response */ public function update(Request $request, $id) { // } }
通過閉包路由獲取參數(shù)
你也可以在路由閉包中使用 Illuminate\Http\Request
類, 服務(wù)容器會自動的將請求參數(shù)注入到路由閉包中:
use Illuminate\Http\Request; Route::get('/', function (Request $request) { // });
請求路徑 & 方法
Illuminate\Http\Request
實例提供了一系列方法來驗證 HTTP 請求參數(shù),并繼承了 Symfony\Component\HttpFoundation\Request
類 。下面是該類的一些重要方法:
獲取請求路徑
path
方法返回請求的路徑信息。所以,如果請求的路徑是 http://domain.com/foo/bar
, path
方法將會返回 foo/bar
:
$uri = $request->path();
is
可以驗證傳入的請求路徑是否與給定的模式匹配。 在這個方法中,你也可以使用 *
字符作為通配符:
if ($request->is('admin/*')) { // }
獲取請求 URL
可以使用 url
或 fullUrl
方法獲取完整的請求 URL。 url
方法返回不含有查詢串的 URL, fullUrl
獲取包含查詢串的 URL:
// 不附帶查詢串... $url = $request->url(); // 附帶查詢串... $url = $request->fullUrl();
獲取請求 Method
method
方法返回請求的 HTTP 動作。還可以使用 isMethod
方法校驗 HTTP 動作是否與給定的客串上匹配:
$method = $request->method();if ($request->isMethod('post')) { // }
PSR-7 請求
PSR-7 standard 定義了 HTTP 消息接口,包括 請求 和 響應(yīng)。如果你想用 PSR-7 請求代替 Laravel 請求,需要先安裝幾個庫。 Laravel 使用 Symfony HTTP Message Bridge 組件將典型的 Laravel 請求 和 響應(yīng) 轉(zhuǎn)換為 PSR-7 兼容實現(xiàn):
composer require symfony/psr-http-message-bridge composer require zendframework/zend-diactoros
一旦安裝了這些庫,就可以通過在路由閉包或控制器方法中的請求接口類型提示來獲取 PSR-7 請求:
use Psr\Http\Message\ServerRequestInterface; Route::get('/', function (ServerRequestInterface $request) { // });
{tip} 如果從路由或控制器返回 PSR-7 響應(yīng)實例,框架會自動將其轉(zhuǎn)換回 Laravel 響應(yīng)實例并顯示。
輸入的裁剪和標(biāo)準化
默認情況下,Laravel 在應(yīng)用的全局中間件堆棧中包含了 TrimStrings
和 ConvertEmptyStringsToNull
中間件。這些中間件被放在 App\Http\Kernel
類的堆棧列表中。它們自動裁剪請求中的所有輸入字符串域,同時將空字符串域轉(zhuǎn)換為 null
。這樣一來,你就不必擔(dān)心路由和控制器中的標(biāo)準化規(guī)約問題。
如果想要禁用這個行為,只需要通過從 App\Http\Kernel
類的 $middleware
屬性中移除它(相當(dāng)于從應(yīng)用的中間件堆棧中移除)。
獲取輸入
獲取所有的輸入數(shù)據(jù)
可以使用 all
方法獲取所有輸入數(shù)據(jù)數(shù)組:
$input = $request->all();
獲取單個輸入值
使用一些簡便方法,就可以通 實例過 Illuminate\Http\Request
實例獲取用戶的全部輸入,不需要擔(dān)心用戶請求用的是哪種 HTTP 動作。無論哪種 HTTP 動作, 用戶的請求都能被 input
方法獲?。?/p>
$name = $request->input('name');
可以將默認值作為傳遞給 input
方法的第二個參數(shù)。這個值將在請求沒有包含該參數(shù)時被返回:
$name = $request->input('name', 'Sally');
當(dāng)與包含數(shù)組輸入的表單協(xié)作時,使用 「點」 運算符訪問數(shù)組元素:
$name = $request->input('products.0.name'); $names = $request->input('products.*.name');
不帶參數(shù)調(diào)用 input
方法,能夠獲取全部輸入值(關(guān)聯(lián)數(shù)組形式):
$input = $request->input();
從查詢串中獲取輸入
input
方法從整個請求載體中獲取值(包括查詢串), query
方法則僅從查詢串中獲取值:
$name = $request->query('name');
如果查詢串值不存在,query
方法的第二個參數(shù)將被作為該參數(shù)的默認值被返回:
$name = $request->query('name', 'Helen');
不帶參數(shù)調(diào)用 query
方法,能夠獲取查詢串的所有值(關(guān)聯(lián)數(shù)組形式):
$query = $request->query();
通過動態(tài)屬性獲取輸入
可以通過 Illuminate\Http\Request
實例的動態(tài)屬性訪問用戶輸入。例如,如果應(yīng)用表單包含 name
域,可以像下面這樣訪問該域的值:
$name = $request->name;
在使用動態(tài)屬性時,Laravel 首先會在請求載體中查找參數(shù)的值。如果該值不存在,Lavarel 將在路由參數(shù)中搜索。
獲取 JSON 輸入
當(dāng)向應(yīng)用傳遞 JSON 請求時,可以通過 input
方法訪問 JSON 數(shù)據(jù),只要將請求的 Content-Type
頭設(shè)置為 application/json
。 同樣可以使用 「點」語法訪問 JSON 數(shù)組:
$name = $request->input('user.name');
獲取部分輸入數(shù)據(jù)
如果需要獲取輸入數(shù)據(jù)的子集,可以使用 only
或 except
方法。它們接受單個 array
或者動態(tài)參數(shù)列表:
$input = $request->only(['username', 'password']); $input = $request->only('username', 'password'); $input = $request->except(['credit_card']); $input = $request->except('credit_card');
{tip}
only
方法返回請求中的全部鍵值對;但是它不返回請求中不存在的鍵值對。
判斷輸入值是否存在
has
方法用于判定請求中是否存在指定的值。如果請求中存在該值, has
方法返回 true
:
if ($request->has('name')) { // }
如果給出一個數(shù)組, has
方法將判斷在請求中,指定的值是否全部存在:
if ($request->has(['name', 'email'])) { // }
如果想要判斷一個值在請求中是否存在,并且不為空,需要使用 filled
方法:
if ($request->filled('name')) { // }
舊數(shù)據(jù)
Laravel 允許你在兩次請求之間保持數(shù)據(jù)。這個特性在有效性校驗出錯后重新填充表單時非常有用。不過,如果你使用 Lavarel 自帶 驗證特性,不需要自己手動調(diào)用這些方法因為一些 Laravel 內(nèi)置的驗證功能會自動調(diào)用它們。
將輸入數(shù)據(jù)傳送到 Session
Illuminate\Http\Request
類的 flash
方法將把當(dāng)前的輸入傳送到 session ,在用戶向應(yīng)用發(fā)出這一次請求時它們?nèi)匀豢捎茫?/p>
$request->flash();
可以使用 flashOnly
或 flashExcept
方法將請求數(shù)據(jù)的子集傳送給 session。這些方法常用于將密碼之類的敏感數(shù)據(jù)排除在 session 保持之外:
$request->flashOnly(['username', 'email']);$request->flashExcept('password');
傳送數(shù)據(jù)并跳轉(zhuǎn)
當(dāng)你經(jīng)常需要將輸入傳送至 session 并緊接著跳轉(zhuǎn)至之前的頁面,可以通過在跳轉(zhuǎn)函數(shù)后鏈接調(diào)用 withInput
方法輕易地實現(xiàn):
return redirect('form')->withInput(); return redirect('form')->withInput( $request->except('password') );
獲取舊數(shù)據(jù)
要獲取前一次請求傳送的數(shù)據(jù),可以使用 Request
實例的 old
方法。 old
方法將從 session 拉取之前傳送的值:
$username = $request->old('username');
Laravel 還提供了全局的 old
助手。如果要在 Blade 模板中 顯示舊數(shù)據(jù), old
助手更易用。如果給定域的舊值不存在,它將返回 null
:
<input type="text" name="username" value="{{ old('username') }}">
Cookies
從請求中獲取 Cookies
Lavarel 框架生成的全部 cookies 都是加密的,并且已經(jīng)用授權(quán)碼簽名,這意味著如果它們被客戶端改變就會失效。使用 Illuminate\Http\Request
實例的 cookie
方法可以從請求中獲取 cookie 值:
$value = $request->cookie('name');
也可以使用 Cookie
facade 訪問 cookie 值:
$value = Cookie::get('name');
將 Cookies 附加到響應(yīng)中
可以使用 cookie
方法向輸出的 Illuminate\Http\Response
實例附加 cookie。需要傳遞 名稱、值、cookie 的過期時間(以分鐘為單位)給該方法:
return response('Hello World')->cookie( 'name','value',$minutes );
cookie
還可以接受另外幾個不太常用的參數(shù)。通常這些參數(shù)和 PHP 內(nèi)置的 setcookie 方法的參數(shù)有著相同的作用和意義:
return response('Hello World')->cookie( 'name', 'value', $minutes, $path, $domain, $secure, $httpOnly );
同樣,你可以使用 Cookie
facade 來 「排列」 用于從應(yīng)用中附加到輸出響應(yīng)的 cookies。queue
方法接受一個 Cookie
實例或者用于創(chuàng)建 Cookie
所需的參數(shù)列表。這些 cookies 將在輸出響應(yīng)被發(fā)送至瀏覽器前被附加:
Cookie::queue(Cookie::make('name', 'value', $minutes)); Cookie::queue('name', 'value', $minutes);
生成 Cookie 實例
如果想要生成一個隨后可以提供給響應(yīng)實例的 Symfony\Component\HttpFoundation\Cookie
實例,可以使用全局的 cookie
助手。這個 cookie 在沒有附加到響應(yīng)實例前不會傳回客戶端:
$cookie = cookie('name', 'value', $minutes); return response('Hello World')->cookie($cookie);
文件
獲取上傳的文件
可以使用 Illuminate\Http\Request
實例的 file
方法或者動態(tài)屬性訪問上傳文件。 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
方法基于文件的內(nèi)容猜測匹配的文件擴展名。這個擴展名有可能和客戶端提供的擴展名不同:
$path = $request->photo->path(); $extension = $request->photo->extension();
其它的文件方法
UploadedFile
實例還有另外幾個方法可用。瀏覽 這個類的 API 文檔 可以獲取這些方法的更多信息。
存儲上傳文件
要存儲上傳的文件,先配置好 文件系統(tǒng)。你可以使用 UploadedFile
的 store
方法把上傳文件移動到你的某個磁盤上,該文件可能是本地文件系統(tǒng)中的一個位置,甚至像 Amazon S3 這樣的云存儲位置。
store
方法接受相對于文件系統(tǒng)配置的存儲文件根目錄的路徑。這個路徑不能包含文件名,因為系統(tǒng)會自動生成唯一的 ID 作為文件名。
store
方法還接受可選的第二個參數(shù),用于存儲文件的磁盤名稱。這個方法會返回相對于磁盤根目錄的文件路徑:
$path = $request->photo->store('images'); $path = $request->photo->store('images', 's3');
如果你不想自動生成文件名,那么可以使用 storeAs
方法,它接受路徑、文件名和磁盤名作為其參數(shù):
$path = $request->photo->storeAs('images', 'filename.jpg'); $path = $request->photo->storeAs('images', 'filename.jpg', 's3');
配置可信代理
如果你的應(yīng)用程序運行在失效的 TLS / SSL 證書的負載均衡器后,你可能會注意到你的應(yīng)用程序有時不能生成 HTTPS 鏈接。通常這是因為你的應(yīng)用程序正在從端口 80 上的負載均衡器轉(zhuǎn)發(fā)流量,卻不知道是否應(yīng)該生成安全鏈接。
解決這個問題需要在 Laravel 應(yīng)用程序中包含 App\Http\Middleware\TrustProxies
中間件,這使得你可以快速自定義應(yīng)用程序信任的負載均衡器或代理。你的可信代理應(yīng)該作為這個中間件的 $proxies
屬性的數(shù)組列出。除了配置受信任的代理之外,還可以配置應(yīng)該信任的代理 $header
:
<?php namespace App\Http\Middleware; use Illuminate\Http\Request; use Fideloper\Proxy\TrustProxies as Middleware; class TrustProxies extends Middleware{ /** * 應(yīng)用程序的可信代理列表 * * @var array */ protected $proxies = [ '192.168.1.1', '192.168.1.2', ]; /** * 應(yīng)該用來檢測代理的頭信息 * * @var string */ protected $headers = Request::HEADER_X_FORWARDED_ALL;}
{tip} 如果你使用 AWS 彈性負載平衡,你的
$header
值應(yīng)該是Request::HEADER_X_FORWARDED_AWS_ELB
。常量的更多信息,可用于$headers
屬性,看看 Symfony 的 文檔 信任代理.
信任所有代理
如果你使用 Amazon AWS 或其他的「云」負載均衡器提供程序,你可能不知道負載均衡器的實際 IP 地址。在這種情況下,你可以使用 *
來信任所有代理:
/** * 應(yīng)用程序的可信代理列表 * * @var array */ protected $proxies = '*';