如何使用yii2的快取依賴特性

hiccphp發表於2019-02-26

如何使用yii2的快取依賴特性

概述

快取是Yii2的強大特性之一,合理使用快取技術可以有效地減小伺服器的訪問壓力。Yii2最基本的快取包括資料快取片段快取頁面快取HTTP快取,這部分內容在官方文件中有更加詳細的說明,這裡不再贅述,如有需要可以參考Yii2官方開發文件中的快取部分

頁面快取

資料快取與片段快取都是針對網站中某一部分內容進行的快取,這種快取需要在程式碼部分進行顯示宣告,修改起來比較麻煩。相對的頁面快取則是針對控制器下方法,對這個方法的檢視檔案進行頁面級別的快取。由於頁面快取可以使用行為的形式,對控制器進行注入,修改的時候只要在控制器中修改對應的配置項即可,所以使用頁面快取更加簡單,擴充套件性更強。

快取依賴

一般來說,快取可以增強伺服器的效能,但會一定程度上減弱其互動性。所以需要對快取進行定期的檢查,清理過期資料,填充最新資料,以保證內容的及時準確。在這一點上,Yii2的快取依賴可以有效解決這個問題。Yii2共有五個內建的快取類,如下所示:

  • yiicachingChainedDependency:如果依賴鏈上任何一個依賴產生變化,則依賴改變。
  • yiicachingDbDependency:如果指定 SQL 語句的查詢結果發生了變化,則依賴改變。
  • yiicachingExpressionDependency:如果指定的 PHP 表示式執行結果發生變化,則依賴改變。
  • yiicachingFileDependency:如果檔案的最後修改時間發生變化,則依賴改變。
  • yiicachingTagDependency:將快取的資料項與一個或多個標籤相關聯。 您可以通過呼叫 yiicachingTagDependency::invalidate() 來檢查指定標籤的快取資料項是否有效。

以資料庫依賴DbDependency為例,在控制器IndexController中,宣告依賴關係:

<?php

namespace frontendcontrollers;

use yiiwebController;

class IndexController extends Controller
{
    public function behaviors()
    {
        return [
            [
                `class` => `yiifiltersPageCache`,
                `only` => [`index`],
                `duration` => 60,
                `variations` => [
                    Yii::$app->language,
                ],
                `dependency` => [
                    `class` => `yiicachingDbDependency`,
                    `sql` => `SELECT COUNT(*) FROM post`,
                ],
            ],
        ];
    }

    public function actionIndex()
    {
        return $this->render(`index`);
    }
    
}

如程式碼所示,在行為方法behaviors()中宣告頁面配置的驅動類,only對應為一個陣列,陣列元素是需要快取的方法對應的檢視。duration表示過期時間,單位為秒。variations對應一個陣列,系統會監聽這個陣列中內容是否發生了變化,如果發生變化就會重新整理快取,反之則不會。dependency對應依賴關係,其中class表示快取依賴的類,sql表示一個一條查詢語句。含義就是post資料表中記錄的總條數發生變化時,就可以認為新增或者刪除類某條資料,需要重新整理快取。

鏈式依賴

上面的例子非常簡單,而實際開發往往要更加複雜。有時候一個頁面是否需要重新整理由很多因素決定,不是一個關係就可以描述清楚的。比如說post資料表中既沒有刪除沒有增加,而是更新一條資料,那上面那查詢語句就無法處理類。這時候,可以用SELECT MAX(*) FROM post檢測更新,但內建頁面快取類中無法直接寫入這兩個查詢,這時候可以用鏈式依賴的內建類來解決這個問題。

所謂鏈式依賴,就是將快取依賴關係配置到一個鏈中,一旦鏈中某個關係不成立,就會重新整理快取。
其中yiicachingChainedDependency就是快取依賴的主要實現類。實現程式碼如下所示:

<?php

namespace frontendcontrollers;

use yiiwebController;

class IndexController extends Controller
{
    public function behaviors()
    {
        return [
            `pageCache` => [
                `class` => `yiifiltersPageCache`,
                `only` => [`index`],
                `duration` => 24 * 3600 * 365, // 1 year
                `variations` => [
                    Yii::$app->language,
                    Yii::$app->id
                ],
                `dependency` => [
                    `class` => `yiicachingChainedDependency`,
                    `dependencies` => [
                        new yiicachingDbDependency([`sql` => `SELECT MAX(updated_at) FROM post`]),
                        new yiicachingDbDependency([`sql` => `SELECT COUNT(id) FROM post`]),
                        new yiicachingDbDependency([`sql` => `SELECT MAX(updated_at) FROM category`]),
                        new yiicachingDbDependency([`sql` => `SELECT COUNT(id) FROM category`]),
                        new yiicachingExpressionDependency([`expression`=>`Yii::$app->request->get("id")`]);
                        new yiicachingFileDependency([`fileName`=>`yanying.txt`]);
                    ]
                ],
            ],
        ];
    }

    public function actionIndex()
    {
        return $this->render(`index`);
    }
    
}

如上所示,dependency中配置類Yii2內建的鏈式依賴,並在dependencies中定義類快取依賴關係的“鏈”。當鏈上某個關係不成立時,就會重新整理快取。另外在整個快取頁面中,如果某一小部分並不需要快取,可以將其設定為動態內容,這部分可以檢視官方文件,不過更推薦看原始碼,文件介紹的比較簡單。

總結

Yii2沒有提供HTML頁面靜態化的內建功能,而是提供了快取機制。在開發網站的時候可以通過偽靜態+快取的方式優化內容頁面,並且採用內建的快取依賴和鏈式依賴解決內容過期的問題,通過動態內容的設定處理不需要快取的部分,比如登入後,首頁可以會顯示使用者名稱,這部分就可以用動態內容。

相關文章