请求 请求
简介
Laravel 的 Illuminate\Http\Request
类提供了一种面向对象的方法,可以与应用程序处理的当前 HTTP 请求进行交互, 以及检索与请求一起提交的输入内容,cookies 和文件。
与请求交互
访问请求
要通过依赖注入获得当前 HTTP 请求的实例,您应该在路由闭包或控制器方法上导入 Illuminate\Http\Request
类。 传入的请求实例将由 Laravel 服务容器 自动注入:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 存储一个新用户.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$name = $request->input('name');
//
}
}
如上所述,你也可以在路由闭包上导入Illuminate\Http\Request
类。服务容器在执行时将自动传入请求注入到闭包中:
use Illuminate\Http\Request;
Route::get('/', function (Request $request) {
//
});
依赖注入和路由参数
如果控制器方法也需要路由的参数传入,则应在其引入的依赖后面列出路由参数。您的路由应该定义如下:
use App\Http\Controllers\UserController;
Route::put('/user/{id}', [UserController::class, 'update']);
您应该注入 Illuminate\Http\Request
, 并通过如下定义控制器方法,来访问 id
路由参数:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 更新指定用户
*
* @param \Illuminate\Http\Request $request
* @param string $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
}
请求路径和方法
Illuminate\Http\Request
实例提供了多种方法来检查传入的 Http 请求,并扩展了 Symfony\Component\HttpFoundation\Request
类。下面我们将讨论几 个最重要的方法。
检索请求路径
path
方法返回请求的路径信息。因此,如果传入请求的目标是 http://example.com/foo/bar
,则 path
方法将返回 foo/bar
:
$uri = $request->path();
检查请求路径 / 路由
is
方法允许您验证传入的请求路径是否与给定的模式匹配。使用此方法时,可以使用 *
字符作为通配符:
if ($request->is('admin/*')) {
//
}
使用 routeIs
方法,可以确定传入请求是否与命名路由匹配:
if ($request->routeIs('admin.*')) {
//
}
检索请求 URL
要检索传入请求的完整 URL,你可以使用 url
或 fullUrl
方法。url
方法将返回不包含查询字符串的 URL,而 fullUrl
方法包含查询字符串:
$url = $request->url();
$urlWithQueryString = $request->fullUrl();
如果要 将查询字符串数据附加到当前URL,可以调用 fullUrlWithQuery
方法。此方法将给定的查询字符串变量数组与当前查询字符串合并:
$request->fullUrlWithQuery(['type' => 'phone']);
检索请求方法
method
方法将返回请求的 HTTP 动词。你可以使用 isMethod
方法来验证 HTTP 动词是否匹配给定的字符串:
$method = $request->method();
if ($request->isMethod('post')) {
//
}
请求头
你可以使用 header
方法从 Illuminate\Http\Request
实例中检索一个请求头。如果请求中不存在该头,将返回 null
。然而,header
方法接受一个可选的第二个参数, 如果请求中不存在该头,将返回该参数:
$value = $request->header('X-Header-Name');
$value = $request->header('X-Header-Name', 'default');
hasHeader
方法可用来确定请求是否包含一个给定的头:
if ($request->hasHeader('X-Header-Name')) {
//
}
为了方便起见,bearerToken
方法可用来从 Authorization
头中检索一个 bearer 令牌。如果这样的头不存在,将返回一个空字符串:
$token = $request->bearerToken();
请求 IP 地址
ip
方法可用来检索向你的应用程序发出请求的客户机的 IP
地址:
$ipAddress = $request->ip();
请求协商
Laravel
提供一些通过 Accept
头检查传入请求的请求内容类型的方法。首先,getAcceptableContentTypes
方法将返回一个包含通过请求接受的所有内容类型的数组:
$contentTypes = $request->getAcceptableContentTypes();
accepts
方法接受内容类型的数组,如果请求接受任何内容类型,则返回 true
。否则,将返回 false
:
if ($request->accepts(['text/html', 'application/json'])) {
// ...
}
你可以使用 prefers
方法来确定给定内容类型数组中哪种内容类型最受请求青睐。如果请求不接受任何提供的内容类型,则将返回 null
:
$preferred = $request->prefers(['text/html', 'application/json']);
由于许多应用程序仅提供 HTML
或 JSON
,因此你可以使用 expectsJson
方法来快速确定传入的请求是否需要 JSON
响应:
if ($request->expectsJson()) {
// ...
}
PSR-7 Requests
PSR-7 标准 指定 HTTP 消息的接口,包括请求和响应。如果要获取 PSR-7 请求的实例而不是 Laravel 请求,则首先需要安装一些库。Laravel 使用 Symfony HTTP Message Bridge 组件将典型的 Laravel 请求和响应转换为 PSR-7 兼容的实现:
composer require symfony/psr-http-message-bridge
composer require nyholm/psr7
一旦安装了这些库,就可以通过在路由闭包或控制器方法上键入请求接口的类型来获取 PSR-7 请求:
use Psr\Http\Message\ServerRequestInterface;
Route::get('/', function (ServerRequestInterface $request) {
//
});
技巧:如果从路由或控制器返回 PSR-7 响应实例,它将自动转换回 Laravel 响应实例并由框架显示。
输入
检索输入
检索所有输入数据
可以使用 all
方法以 array
的形式检索所有传入请求的输入数据。无论传入的请求是来自 HTML 表单还是 XHR 请求,都可以使用此方法。
$input = $request->all();
使用 collect
方法,您可以将所有传入请求的输入数据检索为collection:
$input = $request->collect();
collect
方法还允许您以集合的形式检索传入请求输入的子集:
$request->collect('users')->each(function ($user) {
// ...
});
检索一个输入值
使用一些简单的方法,可以从 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');
可以不带任何参数地调用 input
方法,以便将所有输入值作为关联数组进行检索:
$input = $request->input();
从查询字符串中检索输入
当 input
方法从整个请求有效负载(包括查询字符串)中检索值时,query
方法将仅从查询字符串中检索值:
$name = $request->query('name');
如果请求的查询字符串的值不存在,则将返回此方法的第二个参数:
$name = $request->query('name', 'Helen');
你可以不带任何参数地调用 query
方法,以将所有查询字符串值作为关联数组来检索:
$query = $request->query();
检索 JSON 输入值
向应用程序发送 JSON 请求时,只要将请求的 Content-Type
标头正确设置为 application/json
,就可以通过 input
方法访问 JSON 数据。甚至可以使用 .
语法来检索嵌套在 JSON 数组中的值:
$name = $request->input('user.name');
检索布尔输入值
当处理诸如复选框之类的 HTML 元素时,你的应用程序可能会收到实际上是字符串的「true」值。例如,「true」或「on」。为了方便起见,你可以使用 boolean 方法将这些值作为布尔值检索。boolean
方法为 1,「1」,true,「true」,「on」和「yes」返回 true
。所有其他值将返回 false
:
$archived = $request->boolean('archived');
检索日期输入值
为方便起见,包含日期/时间的输入值可以使用 date
方法作为实例检索。如果请求不包含具有给定名称的输入值,则返回 null
:
$birthday = $request->date('birthday');
date
方法接受的第二个和第三个参数可分别用于指定日期的格式和时区:
$elapsed = $request->date('elapsed', '!H:i', 'Europe/Madrid');
如果输入值存在,但格式无效,将抛出 InvalidArgumentException
;因此,建议您在调用 date
方法之前验证输入。
通过动态属性检索输入
您还可以使用 Illuminate\Http\Request
实例上的动态属性访问用户输入。例如,如果你的应用程序形式之一包含一个 name
字段,则可以像下面这样访问该字段的值:
$name = $request->name;
使用动态属性时,Laravel 将首先在请求有效负载中查找参数的值。如果不存在,Laravel 将在匹配的路线参数中搜索该字段。