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原理后,相信大家都知道答案了吧!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM