Skip to content

HTTP 请求

访问请求

要通过依赖注入获取当前 HTTP 请求的实例,您应该在控制器构造函数或方法中类型提示 Illuminate\Http\Request 类。当前请求实例将由服务容器自动注入:

php
<?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');

        //
    }
}

如果您的控制器方法还期望从路由参数中获取输入,只需在其他依赖项之后列出您的路由参数。例如,如果您的路由定义如下:

php
Route::put('user/{id}', 'UserController@update');

您仍然可以类型提示 Illuminate\Http\Request 并通过如下定义控制器方法来访问路由参数 id

php
<?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 实例提供了多种方法来检查应用程序的 HTTP 请求,并扩展了 Symfony\Component\HttpFoundation\Request 类。以下是此类中一些有用的方法:

检索请求 URI

path 方法返回请求的 URI。因此,如果传入请求的目标是 http://domain.com/foo/bar,则 path 方法将返回 foo/bar

php
$uri = $request->path();

is 方法允许您验证传入请求 URI 是否与给定模式匹配。使用此方法时,您可以使用 * 字符作为通配符:

php
if ($request->is('admin/*')) {
    //
}

要获取完整的 URL,而不仅仅是路径信息,您可以在请求实例上使用 urlfullUrl 方法:

php
// 无查询字符串...
$url = $request->url();

// 带查询字符串...
$url = $request->fullUrl();

您还可以获取完整的 URL 并附加查询参数。例如,如果请求的目标是 http://domain.com/foo,则以下方法将返回 http://domain.com/foo?bar=baz

php
$url = $request->fullUrlWithQuery(['bar' => 'baz']);

检索请求方法

method 方法将返回请求的 HTTP 动词。您还可以使用 isMethod 方法来验证 HTTP 动词是否与给定字符串匹配:

php
$method = $request->method();

if ($request->isMethod('post')) {
    //
}

PSR-7 请求

PSR-7 标准指定了 HTTP 消息的接口,包括请求和响应。如果您想获取 PSR-7 请求的实例,首先需要安装一些库。Laravel 使用 Symfony HTTP Message Bridge 组件将典型的 Laravel 请求和响应转换为 PSR-7 兼容的实现:

php
composer require symfony/psr-http-message-bridge

composer require zendframework/zend-diactoros

安装这些库后,您可以通过在路由或控制器上简单地类型提示请求类型来获取 PSR-7 请求:

php
use Psr\Http\Message\ServerRequestInterface;

Route::get('/', function (ServerRequestInterface $request) {
    //
});

如果您从路由或控制器返回 PSR-7 响应实例,它将自动转换回 Laravel 响应实例并由框架显示。

检索输入

检索输入值

使用一些简单的方法,您可以从 Illuminate\Http\Request 实例访问所有用户输入。您无需担心请求使用的 HTTP 动词,因为输入的访问方式对于所有动词都是相同的:

php
$name = $request->input('name');

您可以将默认值作为第二个参数传递给 input 方法。如果请求的输入值不存在于请求中,则将返回此值:

php
$name = $request->input('name', 'Sally');

在处理带有数组输入的表单时,您可以使用“点”符号来访问数组:

php
$name = $request->input('products.0.name');

$names = $request->input('products.*.name');

检索 JSON 输入值

在向应用程序发送 JSON 请求时,只要请求的 Content-Type 头正确设置为 application/json,您就可以通过 input 方法访问 JSON 数据。您甚至可以使用“点”语法深入到 JSON 数组中:

php
$name = $request->input('user.name');

确定输入值是否存在

要确定请求中是否存在某个值,您可以使用 has 方法。has 方法返回 true,如果该值存在不是空字符串:

php
if ($request->has('name')) {
    //
}

检索所有输入数据

您还可以使用 all 方法将所有输入数据作为 array 检索:

php
$input = $request->all();

检索部分输入数据

如果您需要检索输入数据的子集,可以使用 onlyexcept 方法。这两个方法都接受一个 array 或动态参数列表:

php
$input = $request->only(['username', 'password']);

$input = $request->only('username', 'password');

$input = $request->except(['credit_card']);

$input = $request->except('credit_card');

动态属性

您还可以使用 Illuminate\Http\Request 实例上的动态属性访问用户输入。例如,如果您的应用程序的表单包含一个 name 字段,您可以像这样访问已发布字段的值:

php
$name = $request->name;

使用动态属性时,Laravel 将首先在请求负载中查找参数的值,然后在路由参数中查找。

旧输入

Laravel 允许您在下一个请求期间保留来自一个请求的输入。此功能对于在检测到验证错误后重新填充表单特别有用。但是,如果您使用 Laravel 的验证服务,则不太可能需要手动使用这些方法,因为 Laravel 的一些内置验证功能会自动调用它们。

将输入闪存到会话

Illuminate\Http\Request 实例上的 flash 方法将当前输入闪存到会话,以便在用户的下一个请求期间可用:

php
$request->flash();

您还可以使用 flashOnlyflashExcept 方法将请求数据的子集闪存到会话中:

php
$request->flashOnly(['username', 'email']);

$request->flashExcept('password');

将输入闪存到会话然后重定向

由于您通常希望在重定向到上一页时闪存输入,因此可以使用 withInput 方法轻松地将输入闪存链接到重定向:

php
return redirect('form')->withInput();

return redirect('form')->withInput($request->except('password'));

检索旧数据

要从上一个请求中检索闪存输入,请在 Request 实例上使用 old 方法。old 方法提供了一个方便的助手,用于从会话中提取闪存输入数据:

php
$username = $request->old('username');

Laravel 还提供了一个全局 old 辅助函数。如果您在Blade 模板中显示旧输入,使用 old 辅助函数更为方便。如果给定字符串没有旧输入,将返回 null

php
<input type="text" name="username" value="{{ old('username') }}">

Cookies

从请求中检索 Cookies

Laravel 框架创建的所有 cookies 都经过加密并带有身份验证代码签名,这意味着如果客户端更改了它们,它们将被视为无效。要从请求中检索 cookie 值,您可以在 Illuminate\Http\Request 实例上使用 cookie 方法:

php
$value = $request->cookie('name');

Laravel 提供了一个全局 cookie 辅助函数,作为生成新 Symfony\Component\HttpFoundation\Cookie 实例的简单工厂。可以使用 withCookie 方法将 cookies 附加到 Illuminate\Http\Response 实例:

php
$response = new Illuminate\Http\Response('Hello World');

$response->withCookie('name', 'value', $minutes);

return $response;

要创建一个持续五年的长效 cookie,您可以通过首先调用不带参数的 cookie 辅助函数,然后将 forever 方法链接到返回的 cookie 工厂来使用 cookie 工厂上的 forever 方法:

php
$response->withCookie(cookie()->forever('name', 'value'));

文件

检索上传的文件

您可以使用 Illuminate\Http\Request 实例上的 file 方法访问上传的文件。file 方法返回的对象是 Symfony\Component\HttpFoundation\File\UploadedFile 类的实例,该类扩展了 PHP 的 SplFileInfo 类,并提供了多种方法来与文件交互:

php
$file = $request->file('photo');

您可以使用 hasFile 方法确定请求中是否存在文件:

php
if ($request->hasFile('photo')) {
    //
}

验证上传成功

除了检查文件是否存在,您还可以通过 isValid 方法验证上传文件时是否没有问题:

php
if ($request->file('photo')->isValid()) {
    //
}

移动上传的文件

要将上传的文件移动到新位置,您应该使用 move 方法。此方法会将文件从其临时上传位置(由您的 PHP 配置确定)移动到您选择的更永久的目的地:

php
$request->file('photo')->move($destinationPath);

$request->file('photo')->move($destinationPath, $fileName);

其他文件方法

UploadedFile 实例上还有多种其他方法。有关这些方法的更多信息,请查看类的 API 文档