HTTP 请求
访问请求
要通过依赖注入获取当前 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 string $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 请求,并扩展了 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 请求,您首先需要安装一些库。Laravel 使用 Symfony HTTP Message Bridge 组件将典型的 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 响应实例并由框架显示。
检索输入
检索所有输入数据
您还可以使用 all
方法将所有输入数据作为 array
检索:
$input = $request->all();
检索输入值
使用一些简单的方法,您可以从 Illuminate\Http\Request
实例访问所有用户输入,而无需担心请求使用了哪个 HTTP 动词。无论 HTTP 动词如何,input
方法都可以用来检索用户输入:
$name = $request->input('name');
您可以将默认值作为 input
方法的第二个参数传递。如果请求的输入值不存在于请求中,则返回此值:
$name = $request->input('name', 'Sally');
在处理包含数组输入的表单时,使用“点”符号来访问数组:
$name = $request->input('products.0.name');
$names = $request->input('products.*.name');
通过动态属性检索输入
您还可以使用 Illuminate\Http\Request
实例上的动态属性访问用户输入。例如,如果您的应用程序的表单包含一个 name
字段,您可以像这样访问该字段的值:
$name = $request->name;
使用动态属性时,Laravel 将首先在请求负载中查找参数的值。如果不存在,Laravel 将在路由参数中查找该字段。
检索 JSON 输入值
在向应用程序发送 JSON 请求时,只要请求的 Content-Type
头正确设置为 application/json
,您就可以通过 input
方法访问 JSON 数据。您甚至可以使用“点”语法深入到 JSON 数组中:
$name = $request->input('user.name');
检索部分输入数据
如果您需要检索输入数据的子集,可以使用 only
和 except
方法。这两个方法都接受一个 array
或动态参数列表:
$input = $request->only(['username', 'password']);
$input = $request->only('username', 'password');
$input = $request->except(['credit_card']);
$input = $request->except('credit_card');
确定输入值是否存在
您应该使用 has
方法来确定请求中是否存在某个值。has
方法返回 true
,如果该值存在且不是空字符串:
if ($request->has('name')) {
//
}
旧输入
Laravel 允许您在下一个请求期间保留来自一个请求的输入。此功能对于在检测到验证错误后重新填充表单特别有用。但是,如果您使用 Laravel 的验证功能,则不太可能需要手动使用这些方法,因为 Laravel 的一些内置验证功能会自动调用它们。
将输入闪存到会话
Illuminate\Http\Request
类上的 flash
方法会将当前输入闪存到会话,以便在用户的下一个请求期间可用:
$request->flash();
您还可以使用 flashOnly
和 flashExcept
方法将请求数据的子集闪存到会话中。这些方法对于将敏感信息(如密码)排除在会话之外非常有用:
$request->flashOnly(['username', 'email']);
$request->flashExcept('password');
闪存输入然后重定向
由于您通常希望将输入闪存到会话中,然后重定向到上一页,您可以使用 withInput
方法轻松地将输入闪存链接到重定向:
return redirect('form')->withInput();
return redirect('form')->withInput(
$request->except('password')
);
检索旧输入
要从上一个请求中检索闪存输入,请在 Request
实例上使用 old
方法。old
方法将从会话中提取先前闪存的输入数据:
$username = $request->old('username');
Laravel 还提供了一个全局 old
辅助函数。如果您在Blade 模板中显示旧输入,使用 old
辅助函数更为方便。如果给定字段没有旧输入,将返回 null
:
<input type="text" name="username" value="{{ old('username') }}">
Cookies
从请求中检索 Cookies
Laravel 框架创建的所有 cookies 都经过加密并带有身份验证代码签名,这意味着如果客户端更改了它们,它们将被视为无效。要从请求中检索 cookie 值,请在 Illuminate\Http\Request
实例上使用 cookie
方法:
$value = $request->cookie('name');
将 Cookies 附加到响应
您可以使用 cookie
方法将 cookie 附加到传出的 Illuminate\Http\Response
实例。您应该将名称、值和 cookie 应被视为有效的分钟数传递给此方法:
return response('Hello World')->cookie(
'name', 'value', $minutes
);
cookie
方法还接受一些不太常用的参数。通常,这些参数与传递给 PHP 原生 setcookie 方法的参数具有相同的目的和含义:
return response('Hello World')->cookie(
'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);
生成 Cookie 实例
如果您希望生成一个可以稍后传递给响应实例的 Symfony\Component\HttpFoundation\Cookie
实例,可以使用全局 cookie
辅助函数。除非将此 cookie 附加到响应实例,否则它不会发送回客户端:
$cookie = cookie('name', 'value', $minutes);
return response('Hello World')->cookie($cookie);
文件
检索上传的文件
您可以使用 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
方法接受相对于文件系统配置根目录的路径。此路径不应包含文件名,因为将自动生成一个 UUID 作为文件名。
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');