路由中间件之 AddQueuedCookiesToResponse

未匹配的标注

简介

[
    'App\Http\Middleware\EncryptCookies',
    'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
    'Illuminate\Session\Middleware\StartSession',
    'Illuminate\View\Middleware\ShareErrorsFromSession',
    'App\Http\Middleware\VerifyCsrfToken',
    'Illuminate\Routing\Middleware\SubstituteBindings',
    'App\Http\Middleware\RedirectIfAuthenticated',
]

如上,前面一章我们讲解了 EncryptCookies 路由中间件的作用。

这一章我们来看一下 AddQueuedCookiesToResponse 路由中间件的作用。

从字面上来看,不难看出,大概指从某个专门管理 Cookie 的队列服务中,取出 Cookie 加入到响应中。

Cookie 容器服务

所谓 Cookie 容器服务指提供 Cookie 管理功能的类。即:Illuminate\Cookie\CookieJar

此服务,主要有:

  • 获取 Symfony\Component\HttpFoundation\Cookie 真实 Cookie 对象实例的方法
  • 利用如下数组,实现 Cookie 列表数据的管理

Illuminate\Cookie\CookieJar

protected $queued = [];

AddQueuedCookiesToResponse 中间件

中间件核心方法 handle 方法如下所示:

public function handle($request, Closure $next)
{
    // 从 Laravel 内层获取响应
    $response = $next($request);

    // 直接获取 queued 数组,循环将 Cookie 取出并附加到响应头中
    foreach ($this->cookies->getQueuedCookies() as $cookie) {
        $response->headers->setCookie($cookie);
    }

    // 将响应抛给外层
    return $response;
}

问题一:$this->cookies 从哪里来的

<?php

namespace Illuminate\Cookie\Middleware;

use Closure;
// 重点在这,利用 特别篇5 的讲解方式,我们知道 CookieJar 实际指向的是 Illuminate\Cookie\CookieJar
use Illuminate\Contracts\Cookie\QueueingFactory as CookieJar;

class AddQueuedCookiesToResponse
{
    // 声明存储 Cookie 容器服务的属性
    protected $cookies;

    // 标准 IoC/DI 操作
    public function __construct(CookieJar $cookies)
    {
        $this->cookies = $cookies;
    }

    // ... 省略若干代码
}

由此得知,$this->cookiesIlluminate\Cookie\CookieJar 的实例。

问题二: getQueuedCookies 方法在哪?

接续问题一,我们很容易就知道 getQueuedCookies 方法在 Illuminate\Cookie\CookieJar

public function getQueuedCookies()
{
    return $this->queued;
}

直接返回了 $this->queued 数组

问题三:$this->queued 如何被赋值的?

讲这个问题之前,我们先看一下官方文档的一段内容

file

此段内容的位置 ---> 传送门

我们来看最下面这两段代码

Cookie::queue(Cookie::make('name', 'value', $minutes));

Cookie::queue('name', 'value', $minutes);

其中 Cookie 是 'cookie' 单词标识的门面,最终指向的对象恰恰就是 Illuminate\Cookie\CookieJar

我们看一下它的 queue 方法

public function queue(...$parameters)
{
    // 验证第一个参数是否属于 Symfony\Component\HttpFoundation\Cookie 的实例
    if (head($parameters) instanceof Cookie) {
        // 如果第一个参数是 Symfony\Component\HttpFoundation\Cookie 的实例,则取出赋值个 $cookie
        $cookie = head($parameters);
    } else {
        // 如果第一个参数不是属于 Symfony\Component\HttpFoundation\Cookie 的实例,那么则根据这些参数调用 make 方法,获取 Symfony\Component\HttpFoundation\Cookie 的实例。
        $cookie = call_user_func_array([$this, 'make'], $parameters);
    }

    // 核心!!!,以关联数组的形式存储 Cookie
    $this->queued[$cookie->getName()] = $cookie;
}

看到了没,if 语句判断的两种情况正好是官方文档所示的两种操作。

本篇如有错误、不当或者需补充的内容,请各位同僚多提宝贵意见。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~