• Yii2.0 Cookies机制和使用方法


    在实际的项目开发过程中,用到了Yii2.0 Cookies机制!但是遇到一个十分奇葩的问题,同一个YII框架,backend下Cookies能够正常存储于客户端,但是frontend始终不行。文章的最后将会解答这个疑问。

    一、Yii2.0 Cookies的验证机制

    Yii2.0的Cookies不同于常规的PHP的Cookie设置,YII2.0Cookies使用Cookie类自定义名称、值、过期时间;然后将设置好的cookie配置项装载到CookieCollection中。然后服务器端处理完客户端提交的数据后返回触发Yii::$app->response中的事件;将调用Yii::$app->response->send()方法。以下是send()方法的具体内容:

        public function send()
        {
            if ($this->isSent) {
                return;
            }
            $this->trigger(self::EVENT_BEFORE_SEND);
            $this->prepare();
            $this->trigger(self::EVENT_AFTER_PREPARE);
            $this->sendHeaders();
            $this->sendContent();
            $this->trigger(self::EVENT_AFTER_SEND);
            $this->isSent = true;
        }

    其中,$this->sendHeaders()方法中包含对Cookies真正设置的操作,其方法内容如下:

        /**
         * Sends the response headers to the client
         */
        protected function sendHeaders()
        {
            if (headers_sent()) {
                return;
            }
            $statusCode = $this->getStatusCode();
            header("HTTP/{$this->version} $statusCode {$this->statusText}");
            if ($this->_headers) {
                $headers = $this->getHeaders();
                foreach ($headers as $name => $values) {
                    $name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $name)));
                    // set replace for first occurrence of header but false afterwards to allow multiple
                    $replace = true;
                    foreach ($values as $value) {
                        header("$name: $value", $replace);
                        $replace = false;
                    }
                }
            }
            $this->sendCookies();
        }

    其中调用的$this->sendCookies()方法内容如下:

        /**
         * Sends the cookies to the client.
         */
        protected function sendCookies()
        {
            if ($this->_cookies === null) {
                return;
            }
            $request = Yii::$app->getRequest();
            if ($request->enableCookieValidation) {
                if ($request->cookieValidationKey == '') {
                    throw new InvalidConfigException(get_class($request) . '::cookieValidationKey must be configured with a secret key.');
                }
                $validationKey = $request->cookieValidationKey;
            }
            foreach ($this->getCookies() as $cookie) {
                $value = $cookie->value;
                if ($cookie->expire != 1  && isset($validationKey)) {
                    $value = Yii::$app->getSecurity()->hashData(serialize($value), $validationKey);
                }
                setcookie($cookie->name, $value, $cookie->expire, $cookie->path, $cookie->domain, $cookie->secure, $cookie->httpOnly);
            }
            $this->getCookies()->removeAll();
        }

    到这里,相信大家对Yii2.0 Cookies机制有一个全新的认识了吧!

    二、Yii2.0 Cookies的具体使用方法

     1、main.php或main-local.php配置文件中添加以下代码:

            'request' => [
                // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
                'cookieValidationKey' => 'fcuVvgFv0Vex88Qm5N2-h6HH5anM4HEd',
            ],

    2、使用Yii2.0 Cookie类配置具体的Cookie参数:

     1        $rname0 = new Cookie([
     2                       'name' => 'rname_b',
     3                       'value' => '1111111',
     4                       'expire' => time() + 14400 // 设置过期时间(一个月)
     5                   ]);
     6        $ruser0 = new Cookie([
     7                       'name' => 'ruser_b',
     8                       'value' => '2222222',
     9                       'expire' => time() + 14400 // 设置过期时间(一个月)
    10                   ]);

    3、调用Yii::$app->response->cookies实例将配置好的cookies项装载到CookieColletion中:

    $resCookies = Yii::$app->response->cookies;
    
    $resCookies->add($rname0);
    $resCookies->add($ruser0);

    至此,Cookies相关配置操作已经完成,服务端处理完数据将内容发送到客户端将会触发Yii::$app->response中的事件,就会自动将Cookies写进客户端了!是不是很方便呀!

    回到最初的疑问,为什么会出现那么奇葩的现象尼??主要看以下代码有啥区别:

    // 【代码一】cookies正常写入的代码
    echo json_encode($response, JSON_UNESCAPED_UNICODE);
    
    // 【代码二】cookies无法正常写入的代码
    echo json_encode($response, JSON_UNESCAPED_UNICODE);
    exit;

    就因为代码中多了一个exit导致Cookie无法写入客户端。大家了解了YII2.0 Cookies原理后,相信大家都知道答案了吧!

  • 相关阅读:
    [AHOI2006]文本编辑器 Splay tree区间操作
    HDU-3487 Play with Chain Splay tee区间反转,移动
    HDU-4619 Warm up 2 二分匹配
    HDU-4618 Palindrome Sub-Array 暴力枚举
    HDU-4616 Game 树形DP
    HDU-4614 Vases and Flowers 线段树区间更新
    HDU-4612 Warm up 边双连通分量+缩点+最长链
    HDU-4611 Balls Rearrangement 循环节,模拟
    HDU-4605 Magic Ball Game 树状数组+离散+dfs
    HDU-3436 Queue-jumpers 树状数组 | Splay tree删除,移动
  • 原文地址:https://www.cnblogs.com/itsharehome/p/5010732.html
Copyright © 2020-2023  润新知