3分钟短文:Laravel请求对象方法极多,可不是花拳绣腿

2020-09-21 15:28:06 浏览数 (1)

引言

web服务无外乎两点,一个是请求,一个是相应。中间经过一系列的处理,我们是为一个sandbox。无论是请求Request,还是响应Response,每个框架都会浓墨重彩地进行深度设计。

本文我们来说一下laravel的请求对象。

代码时间

一个网络请求在到达应用程序之前,经历了http的路由匹配,握手连接, 数据发送等等或简单,或复杂的步骤。也同样有多重请求方式,如GET POST PUT OPTION DELETE 等等标准协议里的内容。

laravel提供了一个助手函数 request(),暴露了一个上下文的 Request 对象可全局操作。我们本文重点说说 用于的请求数据。

比如有一条路由,我们这样便捷地定义:

代码语言:javascript复制
Route::post('form', function (IlluminateHttpRequest $request) {
    // $request->input()});

在匿名函数中,使用强制类型Request进行注入,变量$request就是一个实例化后的Request对象, 可以访问其属性和方法。

为了演示表单数据的提交,我们构建一个表单:

代码语言:javascript复制
<form method="post" action="/post-route?utm=12345">
    {{ csrf_field() }}
    <input type="text" name="firstName">
    <input type="submit"></form>

在此之前先定义路由,初步把请求体的数据全部打印出来:

代码语言:javascript复制
Route::post('/post-route', function (Request $request) {
    var_dump($request->all());});

调用请求Request的all方法,返回所有字段的值,并格式化为数组,输出内容类似于

代码语言:javascript复制
[
    '_token' => 'CSRF token here',
    'firstName' => 'value',
    'utm' => 12345]

其中要注意的是,为了显示区别,utm参数是querystring内传送的, 而firstName字段,是表单内通过POST方法传送的。两者的请求方法不一样。

那么对于用于csrf拦截的字段_token,系统生成,系统自检,我们在表单中并不使用, 可以使用 except 方法将其排除在外。路由内这样做:

代码语言:javascript复制
Route::post('/post-route', function (Request $request) {
    var_dump($request->except('_token'));});

那么返回数组中,就不会展示 _token 字段了。这类似与黑名单的功能。相对应地使用白名单,手动指定哪些字段需要展示。需要调用 only 方法:

代码语言:javascript复制
Route::post('/post-route', function (Request $request) {
    var_dump($request->only(['firstName', 'utm']));});

对于单个字段,如何判断是否存在呢?有两个方法,一个是 has(),一个是 exists()。这两者是有细微区别的,has方法要求键名存在,且数值不为空;exists方法仅要求键名存在。

代码语言:javascript复制
if ($request->has('invalid_key')) {}

比如上方的代码键名不存在,所以返回 false。如果表单字段 firstName 不填任何值,也即是空字符串。

代码语言:javascript复制
$request->has('firstName'); // false$request->exists('firstName'); // true

所以对于大多数的场景,我们其实是在判断是否存在键名,对值并未判断,所以exists 方法更为合适。

上述的all方法返回所有字段的值,如果用于单一字段值的获取,要使用 input()方法:

代码语言:javascript复制
Route::post('/post-route', function (Request $request) {
    $userName = $request->input('name', 'anonymous');});

第二个参数是指定如果键名不存在时的默认值。

有了input方法,我们来看更复杂的表单提交数组数据的处理办法。首先构造一个表单,并提交数组数据:

代码语言:javascript复制
<form method="post" action="/post-route">
    {{ csrf_field() }}
    <input type="text" name="employees[0][firstName]">
    <input type="text" name="employees[0][lastName]">
    <input type="text" name="employees[1][firstName]">
    <input type="text" name="employees[1][lastName]">
    <input type="submit"></form>

这样的表单真是shit对不对,可是框架需要满足这样的需求。处理起来也没问题。PHP就是最为擅长处理数组,所以轻快。laravel对请求体进行数组操作, 还有更高阶的用法,下面是示例:

代码语言:javascript复制
Route::post('/post-route', function (Request $request) {
    $employeeZeroFirstName = $request->input('employees.0.firstName');
    $allLastNames = $request->input('employees.*.lastName');
    $employeeOne = $request->input('employees.1');});

我们可以使用明确的键名进行访问,也可以使用通配符进行匹配。上面的方法返回值如下, 大家看看不同的写法,输出会有不同。

假设4个输入框传入的值分别是 "Jim" "Smith" "Bob" "Jones",那么打印如下:

代码语言:javascript复制
$employeeZeroFirstName = 'Jim';$allLastNames = ['Smith', 'Jones'];$employeeOne = ['firstName' => 'Bob', 'lastName' => 'Jones'];

laravel按照数组的层级,完整地返回了。整个数组结构大致如下:

代码语言:javascript复制
[
    'employees' => [
        0 => [
            'firstName' => 'Jim',
            'lastName'  => 'Smith',
        ],
        1 => [
            'firstName' => 'Bob',
            'lastName'  => 'Jones',
        ],
    ]]

只不过在访问的时候,使用点的方法;也可以使用通配符进行键名匹配。非常灵活。

写在最后

本文通过示例演示了laravel Request请求常用的方法获取表单数据,最重要也用的最少的数组数据的解析, 可以加深大家对于表单数据处理的逻辑。

Happy coding :-)

0 人点赞