片段緩存(Fragment Caching)

2018-02-24 15:40 更新

片段緩存

片段緩存指的是緩存頁面內(nèi)容中的某個片段。例如,一個頁面顯示了逐年銷售額的摘要表格,可以把表格緩存下來,以消除每次請求都要重新生成表格的耗時。片段緩存是基于數(shù)據(jù)緩存實(shí)現(xiàn)的。

視圖中使用以下結(jié)構(gòu)啟用片段緩存:

if ($this->beginCache($id)) {

    // ... 在此生成內(nèi)容 ...

    $this->endCache();
}

調(diào)用 yii\base\View::beginCache() 和 yii\base\View::endCache() 方法包裹內(nèi)容生成邏輯。如果緩存中存在該內(nèi)容,yii\base\View::beginCache() 方法將渲染內(nèi)容并返回 false,因此將跳過內(nèi)容生成邏輯。否則,內(nèi)容生成邏輯被執(zhí)行,一直執(zhí)行到 yii\base\View::endCache() 時,生成的內(nèi)容將被捕獲并存儲在緩存中。

[數(shù)據(jù)緩存]一樣,每個片段緩存也需要全局唯一的?$id?標(biāo)記。

緩存選項(xiàng)

如果要為片段緩存指定額外配置項(xiàng),請通過向 yii\base\View::beginCache() 方法第二個參數(shù)傳遞配置數(shù)組。在框架內(nèi)部,該數(shù)組將被用來配置一個 yii\widget\FragmentCache 小部件用以實(shí)現(xiàn)片段緩存功能。

過期時間(duration)

或許片段緩存中最常用的一個配置選項(xiàng)就是 yii\widgets\FragmentCache::duration 了。它指定了內(nèi)容被緩存的秒數(shù)。以下代碼緩存內(nèi)容最多一小時:

if ($this->beginCache($id, ['duration' => 3600])) {

    // ... 在此生成內(nèi)容 ...

    $this->endCache();
}

如果該選項(xiàng)未設(shè)置,則默認(rèn)為 0,永不過期。

依賴

[數(shù)據(jù)緩存]一樣,片段緩存的內(nèi)容一樣可以設(shè)置緩存依賴。例如一段被緩存的文章,是否重新緩存取決于它是否被修改過。

通過設(shè)置 yii\widgets\FragmentCache::dependency 選項(xiàng)來指定依賴,該選項(xiàng)的值可以是一個 yii\caching\Dependency 類的派生類,也可以是創(chuàng)建緩存對象的配置數(shù)組。以下代碼指定了一個片段緩存,它依賴于?update_at?字段是否被更改過的。

$dependency = [
    'class' => 'yii\caching\DbDependency',
    'sql' => 'SELECT MAX(updated_at) FROM post',
];

if ($this->beginCache($id, ['dependency' => $dependency])) {

    // ... 在此生成內(nèi)容 ...

    $this->endCache();
}

變化

緩存的內(nèi)容可能需要根據(jù)一些參數(shù)的更改而變化。例如一個 Web 應(yīng)用支持多語言,同一段視圖代碼也許需要生成多個語言的內(nèi)容。因此可以設(shè)置緩存根據(jù)應(yīng)用當(dāng)前語言而變化。

通過設(shè)置 yii\widgets\FragmentCache::variations 選項(xiàng)來指定變化,該選項(xiàng)的值應(yīng)該是一個標(biāo)量,每個標(biāo)量代表不同的變化系數(shù)。例如設(shè)置緩存根據(jù)當(dāng)前語言而變化可以用以下代碼:

if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {

    // ... 在此生成內(nèi)容 ...

    $this->endCache();
}

開關(guān)

有時你可能只想在特定條件下開啟片段緩存。例如,一個顯示表單的頁面,可能只需要在初次請求時緩存表單(通過 GET 請求)。隨后請求所顯示(通過 POST 請求)的表單不該使用緩存,因?yàn)榇藭r表單中可能包含用戶輸入內(nèi)容。鑒于此種情況,可以使用 yii\widgets\FragmentCache::enabled 選項(xiàng)來指定緩存開關(guān),如下所示:

if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {

    // ... 在此生成內(nèi)容 ...

    $this->endCache();
}

緩存嵌套

片段緩存可以被嵌套使用。一個片段緩存可以被另一個包裹。例如,評論被緩存在里層,同時整個評論的片段又被緩存在外層的文章中。以下代碼展示了片段緩存的嵌套使用:

if ($this->beginCache($id1)) {

    // ...在此生成內(nèi)容...

    if ($this->beginCache($id2, $options2)) {

        // ...在此生成內(nèi)容...

        $this->endCache();
    }

    // ...在此生成內(nèi)容...

    $this->endCache();
}

可以為嵌套的緩存設(shè)置不同的配置項(xiàng)。例如,內(nèi)層緩存和外層緩存使用不同的過期時間。甚至當(dāng)外層緩存的數(shù)據(jù)過期失效了,內(nèi)層緩存仍然可能提供有效的片段緩存數(shù)據(jù)。但是,反之則不然。如果外層片段緩存沒有過期而被視為有效,此時即使內(nèi)層片段緩存已經(jīng)失效,它也將繼續(xù)提供同樣的緩存副本。因此,你必須謹(jǐn)慎處理緩存嵌套中的過期時間和依賴,否則外層的片段很有可能返回的是不符合你預(yù)期的失效數(shù)據(jù)。

譯注:外層的失效時間應(yīng)該短于內(nèi)層,外層的依賴條件應(yīng)該低于內(nèi)層,以確保最小的片段,返回的是最新的數(shù)據(jù)。

動態(tài)內(nèi)容

使用片段緩存時,可能會遇到一大段較為靜態(tài)的內(nèi)容中有少許動態(tài)內(nèi)容的情況。例如,一個顯示著菜單欄和當(dāng)前用戶名的頁面頭部。還有一種可能是緩存的內(nèi)容可能包含每次請求都需要執(zhí)行的 PHP 代碼(例如注冊資源包的代碼)。這兩個問題都可以使用動態(tài)內(nèi)容功能解決。

動態(tài)內(nèi)容的意思是這部分輸出的內(nèi)容不該被緩存,即便是它被包裹在片段緩存中。為了使內(nèi)容保持動態(tài),每次請求都執(zhí)行 PHP 代碼生成,即使這些代碼已經(jīng)被緩存了。

可以在片段緩存中調(diào)用 yii\base\View::renderDynamic() 去插入動態(tài)內(nèi)容,如下所示:

if ($this->beginCache($id1)) {

    // ...在此生成內(nèi)容...

    echo $this->renderDynamic('return Yii::$app->user->identity->name;');

    // ...在此生成內(nèi)容...

    $this->endCache();
}

yii\base\View::renderDynamic() 方法接受一段 PHP 代碼作為參數(shù)。代碼的返回值被看作是動態(tài)內(nèi)容。這段代碼將在每次請求時都執(zhí)行,無論其外層的片段緩存是否被存儲。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號