?
Ce document utilise Manuel du site Web PHP chinois Libérer
數據緩存是指將一些 PHP 變量存儲到緩存中,使用時再從緩存中取回。它也是更高級緩存特性的基礎,例如查詢緩存和內容緩存。
如下代碼是一個典型的數據緩存使用模式。其中?$cache
?指向緩存組件:
// 嘗試從緩存中取回 $data $data = $cache->get($key);
if ($data === false) {
// $data 在緩存中沒有找到,則重新計算它的值
// 將 $data 存放到緩存供下次使用
$cache->set($key, $data);
}
// 這兒 $data 可以使用了。
數據緩存需要緩存組件提供支持,它代表各種緩存存儲器,例如內存,文件,數據庫。
緩存組件通常注冊為應用程序組件,這樣它們就可以在全局進行配置與訪問。如下代碼演示了如何配置應用程序組件?cache
?使用兩個memcached?服務器:
'components' => [
'cache' => [
'class' => 'yii\caching\MemCache',
'servers' => [
[
'host' => 'server1',
'port' => 11211,
'weight' => 100,
],
[
'host' => 'server2',
'port' => 11211,
'weight' => 50,
],
],
],
],
然后就可以通過?Yii::$app->cache
?訪問上面的緩存組件了。
由于所有緩存組件都支持同樣的一系列 API ,并不需要修改使用緩存的業(yè)務代碼就能直接替換為其他底層緩存組件,只需在應用配置中重新配置一下就可以。例如,你可以將上述配置修改為使用 yii\caching\ApcCache:
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
],
],
Tip: 你可以注冊多個緩存組件,很多依賴緩存的類默認調用名為?
cache
?的組件(例如 yii\web\UrlManager)。
Yii 支持一系列緩存存儲器,概況如下:
Yii::$app->cache->get($key)
?嘗試從緩存中取回數據而不用擔心Yii::$app->cache
?可能是?null
。Tip: 你可以在同一個應用程序中使用不同的緩存存儲器。一個常見的策略是使用基于內存的緩存存儲器存儲小而常用的數據(例如:統計數據),使用基于文件或數據庫的緩存存儲器存儲大而不太常用的數據(例如:網頁內容)。
所有緩存組件都有同樣的基類 yii\caching\Cache ,因此都支持如下 API:
有些緩存存儲器如 MemCache,APC 支持以批量模式取回緩存值,這樣可以節(jié)省取回緩存數據的開支。 yii\caching\Cache::mget() 和 yii\caching\Cache::madd() API提供對該特性的支持。如果底層緩存存儲器不支持該特性,Yii 也會模擬實現。
由于 yii\caching\Cache 實現了 PHP?ArrayAccess
?接口,緩存組件也可以像數組那樣使用,下面是幾個例子:
$cache['var1'] = $value1; // 等價于: $cache->set('var1', $value1);$value2 = $cache['var2']; // 等價于: $value2 = $cache->get('var2');
存儲在緩存中的每項數據都通過鍵作唯一識別。當你在緩存中存儲一項數據時,必須為它指定一個鍵,稍后從緩存中取回數據時,也需要提供相應的鍵。
你可以使用一個字符串或者任意值作為一個緩存鍵。當鍵不是一個字符串時,它將會自動被序列化為一個字符串。
定義一個緩存鍵常見的一個策略就是在一個數組中包含所有的決定性因素。例如,yii\db\Schema 使用如下鍵存儲一個數據表的結構信息。
[
__CLASS__, // 結構類名
$this->db->dsn, // 數據源名稱
$this->db->username, // 數據庫登錄用戶名
$name, // 表名
];
如你所見,該鍵包含了可唯一指定一個數據庫表所需的所有必要信息。
當同一個緩存存儲器被用于多個不同的應用時,應該為每個應用指定一個唯一的緩存鍵前綴以避免緩存鍵沖突。可以通過配置 yii\caching\Cache::keyPrefix 屬性實現。例如,在應用配置中可以編寫如下代碼:
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
'keyPrefix' => 'myapp', // 唯一鍵前綴
],
],
為了確?;ネㄐ裕颂幹荒苁褂米帜负蛿底?。
默認情況下,緩存中的數據會永久存留,除非它被某些緩存策略強制移除(例如:緩存空間已滿,最老的數據會被移除)。要改變此特性,你可以在調用 yii\caching\Cache::set() 存儲一項數據時提供一個過期時間參數。該參數代表這項數據在緩存中可保持有效多少秒。當你調用 yii\caching\Cache::get() 取回數據時,如果它已經過了超時時間,該方法將返回 false,表明在緩存中找不到這項數據。例如:
// 將數據在緩存中保留 45 秒$cache->set($key, $data, 45);
sleep(50);
$data = $cache->get($key);
if ($data === false) {
// $data 已過期,或者在緩存中找不到
}
除了超時設置,緩存數據還可能受到緩存依賴的影響而失效。例如,yii\caching\FileDependency 代表對一個文件修改時間的依賴。這個依賴條件發(fā)生變化也就意味著相應的文件已經被修改。因此,緩存中任何過期的文件內容都應該被置為失效狀態(tài),對 yii\caching\Cache::get() 的調用都應該返回 false。
緩存依賴用 yii\caching\Dependency 的派生類所表示。當調用 yii\caching\Cache::set() 在緩存中存儲一項數據時,可以同時傳遞一個關聯的緩存依賴對象。例如:
// 創(chuàng)建一個對 example.txt 文件修改時間的緩存依賴$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);
// 緩存數據將在30秒后超時// 如果 example.txt 被修改,它也可能被更早地置為失效狀態(tài)。$cache->set($key, $data, 30, $dependency);
// 緩存會檢查數據是否已超時。// 它還會檢查關聯的依賴是否已變化。// 符合任何一個條件時都會返回 false。$data = $cache->get($key);
下面是可用的緩存依賴的概況:
查詢緩存是一個建立在數據緩存之上的特殊緩存特性。它用于緩存數據庫查詢的結果。
查詢緩存需要一個 yii\db\Connection 和一個有效的?cache
?應用組件。查詢緩存的基本用法如下,假設?$db
?是一個 yii\db\Connection 實例:
$duration = 60; // 緩存查詢結果60秒$dependency = ...; // 可選的緩存依賴
$db->beginCache($duration, $dependency);
// ...這兒執(zhí)行數據庫查詢...
$db->endCache();
如你所見,beginCache()
?和?endCache()
?中間的任何查詢結果都會被緩存起來。如果緩存中找到了同樣查詢的結果,則查詢會被跳過,直接從緩存中提取結果。
查詢緩存可以用于?ActiveRecord?和?DAO。
Info: 有些 DBMS (例如:MySQL)也支持數據庫服務器端的查詢緩存。你可以選擇使用任一查詢緩存機制。上文所述的查詢緩存的好處在于你可以指定更靈活的緩存依賴因此可能更加高效。
查詢緩存有兩個通過 yii\db\Connection 設置的配置項:
'cache'
。只有在設置了一個有效的緩存應用組件時,查詢緩存才會有效。當查詢結果中含有資源句柄時,查詢緩存無法使用。例如,在有些 DBMS 中使用了?BLOB
?列的時候,緩存結果會為該數據列返回一個資源句柄。