首页 » Laravel 5.3 中文文档 » 正文

「Laravel 5.3 中文文档」HTTP 层 – 请求

访问请求

要通过依赖注入获取当前 HTTP 请求的实例,你需要在类的控制器方法中使用 Illuminate\Http\Request 类型提示。进入的请求实例将会通过服务容器自动注入:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Store a new user.
     *
     * @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
{
    /**
     * Update the specified user.
     *
     * @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:

// 不带查询字符串
$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 消息桥接组件来把典型的 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 动词,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 数据。你甚至可以使用“点”语法来获取 JOSN 数组中的值:

$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');

判断输入值是否存在

你可以使用 has 方法来判断输入中某个值是否存在。如果该值存在则 has 方法会返回 true,否则会返回一个空字符串:

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

旧输入数据

Laravel 允许你在下次请求前保存本次请求数据。这个特性对于验证失败后重新填写表单非常有用。然而,如果你使用 Laravel 自带的验证服务,那就不需要你手动使用该方法,因为 Laravel 的一些内置验证功能会自动调用它们。

闪存输入到 Session

Illuminate\Http\Request 类的 flush 方法会闪存当前输入数据到 session,以便在用户下次请求进入前都可以访问它们:

$request->flash();

你还可以使用 flashOnly 和 flashExcept 方法来闪存一部分请求数据到 session。这些方法可以确保一些敏感信息如密码不被闪存到 session:

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

$request->flashExcept('password');

闪存输入后重定向

由于你可能经常需要闪存输入数据到 session 然后重定向回前一页,你可以链式调用 withInput 方法把输入闪存轻松加到重定向后:

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

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

获取旧的输入值

要从前一个请求中获取闪存值,你可以使用 Request 实例中的 old 方法,old 方法会从 session 中获取上一次闪存的输入值:

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

Laravel 还提供了一个全局的 old 辅助方法。如果你想在 Blade 模板中显示旧的输入值,使用 old 辅助方法会更加简单。如果给定的旧的输入值不存在,则会返回 null:

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

Cookies

从请求中获取 cookie

Laravel 框架创建的所有 cookie 都是经过加密的,并通过一个授权码进行签名,如果它们被客户端修改过,那它们将会被认为是无效的。要从请求中获取 cookie 的值,使用 Illuminate\Http\Request 实例中的 cooike 方法:

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

向响应中附加 cookies

你还可以在 Illuminate\Http\Response 实例上使用 cookie 方法来给其附加 cookie。你需要给该方法传递一个名称、值、以及该 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 方法接收一个路径,这个路径是文件将被存储的,你配置好的根目录的相对路径。这个路径不应该包含文件名,因为文件名会根据文件内容是由 MD5 哈希值自动生成。

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

 


该篇属于专题:《Laravel 5.3 中文文档

发表评论