Laravel 文档阅读: HTTP 请求

获得请求实例

在控制器方法里,可以通过依赖注入的方式自动获得咱们的请求实例,也就是 Illuminate\Http\Request 类实例,这是用服务容器注入的。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UsersController extends Controller
{
    /**
     * Store a new user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $name = $request->input('name');

        //
    }
}

依赖注入 & 路由参数

如果控制器方法还要接收路由参数,你应该把接收路由参数的参数位置放在所有依赖注入参数之后。比如,有这么一个路由:

Route::put('users/{id}', 'UsersController@update');

在控制器方法里,你还要依赖注入请求实例,还要呢,接收路由参数 id。那你就要这么做:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UsersController extends Controller
{
    /**
     * Update the specified user.
     *
     * @param  Request  $request
     * @param  string  $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        //
    }
}

在路由的闭包里获得请求实例

在基于闭包的路由中,可以依赖注入请求实例:

use Illuminate\Http\Request;

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

请求路径 & 请求方法

Illuminate\Http\Request 实例对象提供了许多丰富的、检查应用程序中的 HTTP 请求信息的方法,并且 Illuminate\Http\Request 类自身继承了 Symfony\Component\HttpFoundation\Request。在这里,我们仅讨论几个重要的方法。

获得请求路径

path 方法返回请求路径信息。如果请求路径是 http://domain.com/foo/bar,那么用 path 方法得到的值是 foo/bar

$uri = $request->path();

path 方法验证当前的请求路径是否匹配给定的模式。你还可以使用通配符 *

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

获得请求 URL

获得请求的完整路径请使用 urlfullUrl 方法。url 方法会返回不包含请求字符串的 URL,而 fullUrl 方法会返回包含请求字符串的 URL。

// Without Query String...
$url = $request->url();

// With Query String...
$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 响应实例,便于框架处理。

TrimStringsConvertEmptyStringsToNull 中间件

App\Http\Kernel 类的 $middleware 属性里,包含两个中间件,TrimStringsConvertEmptyStringsToNull,它们会在应用程序的每次请求中使用。TrimStrings 中间件用来修剪字符串(比如去掉字符串两端的空格);ConvertEmptyStringsToNull 中间件将空字符串转换为 null,这就省去了我们一些琐碎的工作,得到规范化的字符串了。

如果要禁用这两个中间件,只要从 $middleware 属性中移除掉就可以了。

获得输入数据

获得输入数据的过程,就是操作 Illuminate\Http\Request 实例方法的过程。

获得所有的输入数据

使用 all 方法。该方法会得到一个数组,数组里就是输入数据。

$input = $request->all();

获得一条输入数据值

使用 input 方法,不论 HTTP 的请求类型如何,input 方法都能获得请求里的数据。

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

还可以为 input 方法传递第二个参数,作为字段缺省值。当请求字段不在输入数据中,就会使用这个值。

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

当操作数组形式的输入数据时,使用点(.)符号:

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

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

获得查询字符串

input 方法是从整个请求中搜罗输入数据的,包括表单数据、查询字符串和路由参数等。但如果只是要从查询字符串获得输入数据的话,就使用 query 方法:

$name = $request->query('name');

同样,如果查询字段没有出现在查询字符串中,还可以为它指定缺省值:

$name = $request->query('name', 'Helen');

直接使用 query() 方法得到是一个包含所有查询字符串数据的关联数组:

$query = $request->query();

通过动态属性获得数据数据

可以在 Illuminate\Http\Request 实例上直接使用动态属获得输入数据。例如,如果传递过来的表单数据里包含一个 name 字段,可以这样获得它的值:

$name = $request->name;

使用动态属性时,Laravel 会从请求中尽可能得搜罗输入数据值,如果没找到,再去找路由参数。

获得 JSON 格式中的数据值

当项目接收的是 JSON 请求,也就是请求的 Content-Type 标头值为 application/json 的时候,使用点(.)符号获得 JSON 字段值:

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

获得局部输入数据

有时只需要获得输入数据的一个子集,这时要用到 onlyexcept 方法。这两个方法接收一个数组或者参数列表:

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

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

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

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

需要注意的是,only 方法中列举的字段如果没有出现在请求字段里,那么最终返回的结果中将不会包含这个字段数据。

判断输入数据是否存在

使用 has 方法,该方法返回一个布尔值。如果请求数据里包含此字段,就会返回 true,否则返回 false

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

has 方法还可以接收一个数组,返回的结果值表示是否数组里的所有字段都出现在了输入数据中:

if ($request->has(['name', 'email'])) {
    //
}

如果要 判断出现在输入数据中的字段值是否为空,使用 filled 方法

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

旧输入数据

Laravel 能够将本次请求的数据保留到下一次,这个特性能实现表单验证失败后,再次返回表单填写页的时候,旧输入数据仍然填充在表单里。如果使用了 Laravel 的本身的验证特性,更是不需要你手动使用下面要说的这些方法了,因为内置的验证功能会自动调用这些方法。

闪存数据到 Session

Illuminate\Http\Request 类的 flash 方法会将当前输入数据闪存到 Session 中,使得在下一次的请求中还能获得这些数据。

$request->flash();

或者使用 flashOnly/flashExcept 方法闪存一部分数据到 Session。这两个方法能让一些诸如密码的敏感信息不保存在 Session 中。

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

$request->flashExcept('password');

闪存数据后重定向

通常我们会在闪存完数据后,重定向到之前的页面。可以在 redirect 方法屁股后头跟上 withInput 方法实现这个功能:

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

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

获得旧数据

获得之前的请求闪存到 Session 里的数据,使用 Request 实例的 old 方法。old 方法会拉出闪存到 Session 中的对应数据:

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

Laravel 还提供了一个全局的 old 辅助函数。在 Blade 模板里面使用这个方法显示数据会更加方便。如果 Session 中闪存的数据里不包含该条,就直接返回 null

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

Cookies

从请求中获得 Cookie

Laravel 中生成的 Cookie 都会经过加密,并且使用认证码进行签名,所以客户端上的 Cookie 修改都被视为无效。获得请求里的 Cookie 值,使用 Illuminate\Http\Request 实例的 cookie 方法:

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

为响应附加 Cookie

Illuminate\Http\Response 实例中也有一个 cookie 方法,让你可以为响应附加 Cookie,这个方法接收的 3 个参数分别是名称、值和有效时间。

return response('Hello World')->cookie(
    'name', 'value', $minutes
);

cookie 方法还可以接受更多的参数,列举如下:

return response('Hello World')->cookie(
    'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);

通常,这些参数与 PHP 原生 setcookie 方法的参数具有相同的目的和意义。

生成 Cookie 实例

你也可以选择先生成一个 Symfony\Component\HttpFoundation\Cookie实例,在稍晚些将此 Cookie 实例附加到响应上。生成 Cookie 实例使用全局 cookie 辅助函数。只有当 Cookie 实例附加到响应实例上后,才会被发送回客户端:

$cookie = cookie('name', 'value', $minutes);

return response('Hello World')->cookie($cookie);

文件

获得上传文件

使用 Illuminate\Http\Request实例的 file 方法或者动态属性获得上传文件。file 方法返回 Illuminate\Http\UploadedFile 实例,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 文档 获得更多信息。

保存上传文件

保存上传文件,需要先配置 config/filesystems.php 文件。UploadedFile 类有一个 store 方法用来移动上传文件到你的一个「硬盘」里,可能是本地文件系统,也可能是像 Amazon S3 这样的远程云存储服务。

store 方法接收的路径是相对路径,是相对于文件系统根目录的。该路径不应该包含文件名,因为会自动生成一个唯一 ID 作为文件名。

store 方法接收的第二个可选参数是保存文件使用的硬盘。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');

配置可信代理

当你的应用程序运行在终止 TLS / SSL 证书的负载平衡器后面,你可能会看到你的应用程序有时候不生成 HTTPS 链接。通常这是因为您的应用程序正在 80 端口上从你的负载平衡器上转发流量,而且不知道应该生成安全链接。

为了解决这个问题,需要在你的应用程序中使用 App\Http\Middleware\TrustProxies 中间件。这个中间件允许你快速自定义受应用程序信任的负载平衡器或者代理。你的信任代理应该列举在该中间件的 $proxies 属性内。除了配置可信代理之外,您还可以配置代理发送的标头,其中包含有关原始请求的信息:

<?php

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies = [
        '192.168.1.1',
        '192.168.1.2',
    ];

    /**
     * The current proxy header mappings.
     *
     * @var array
     */
    protected $headers = [
        Request::HEADER_FORWARDED => 'FORWARDED',
        Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
        Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
        Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
        Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
    ];
}

信任所有代理

如果你正在使用 Amazon AWS 或其他「云」负载平衡器提供商,可能不知道实际平衡器的 IP 地址。 在这种情况下,您可以使用 ** 来信任所有代理:

/**
 * The trusted proxies for this application.
 *
 * @var array
 */
protected $proxies = '**';
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由 Summer 于 6年前 加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!