Yii 1.1 提供了統一的緩存組件架構,支援文件、數據庫、Memcache、APC、Redis、XCache、WinCache、Zend Data 等多種存儲後端。本文系統講解緩存配置、數據緩存、片段緩存、頁面緩存、動態內容、緩存依賴六大核心場景,助你構建高性能應用。
所有緩存類繼承自 CCache,實現 ICache 介面:
framework/caching/
├── CCache.php # 基類,實現 ArrayAccess
├── CApcCache.php # APC
├── CDbCache.php # 數據庫
├── CDummyCache.php # 空緩存 (開發/測試)
├── CEAcceleratorCache.php # EAccelerator
├── CFileCache.php # 文件 (1.0.6+)
├── CMemCache.php # Memcache
├── CWinCache.php # WinCache
├── CXCache.php # XCache (1.0.1+)
├── CZendDataCache.php # Zend Data Cache (1.0.4+)
└── dependencies/ # 緩存依賴
├── CCacheDependency.php
├── CChainedCacheDependency.php
├── CDbCacheDependency.php
├── CDirectoryCacheDependency.php
├── CExpressionDependency.php
├── CFileCacheDependency.php
└── CGlobalStateCacheDependency.php
// protected/config/main.php
'components' => [
// 文件緩存 (適合大塊數據、頁面片段)
'cache' => [
'class' => 'system.caching.CFileCache',
'cachePath' => 'protected/runtime/cache', // 自定義路徑
],
// Memcache (分佈式、高併發首選)
// 'cache' => [
// 'class' => 'system.caching.CMemCache',
// 'servers' => [
// ['host' => '127.0.0.1', 'port' => 11211, 'weight' => 60],
// ['host' => '192.168.1.10', 'port' => 11211, 'weight' => 40],
// ],
// ],
],
| 方法 | 說明 | 示例 |
|---|---|---|
set($id, $value, $expire, $dependency) | 存儲 | Yii::app()->cache->set('key', $data, 3600) |
get($id) | 讀取 (失效返回 false) | $data = Yii::app()->cache->get('key') |
add($id, $value, $expire, $dependency) | 僅不存在時存儲 | Yii::app()->cache->add('key', $data) |
delete($id) | 刪除 | Yii::app()->cache->delete('key') |
flush() | 清空所有 | Yii::app()->cache->flush() |
mget($ids) | 批量讀取 (1.0.8+) | Yii::app()->cache->mget(['k1','k2']) |
$cache = Yii::app()->cache; $cache['key'] = $value; // 等同 set() $value = $cache['key']; // 等同 get() isset($cache['key']); // 檢查存在 unset($cache['key']); // 等同 delete()
// 文件依賴:文件修改即失效
Yii::app()->cache->set('key', $value, 0, new CFileCacheDependency('/path/to/config.php'));
// 目錄依賴:目錄下任意文件變化失效
new CDirectoryCacheDependency('/path/to/templates');
// 數據庫依賴:SQL 查詢結果變化失效
new CDbCacheDependency('SELECT MAX(updated_at) FROM post');
// 全局狀態依賴:Yii::app()->setGlobalState() 變量變化失效
new CGlobalStateCacheDependency('app.version');
// 表達式依賴:PHP 表達式結果變化失效 (1.0.4+)
new CExpressionDependency('Yii::app()->user->isGuest');
// 鏈式依賴:任一依賴變化即失效
new CChainedCacheDependency([
new CFileCacheDependency('/path/a'),
new CDbCacheDependency('SELECT ...'),
]);
// 視圖文件中
beginCache('sidebar', [
'duration' => 3600, // 1 小時
'dependency' => [
'class' => 'system.caching.dependencies.CDbCacheDependency',
'sql' => 'SELECT MAX(updated_at) FROM category',
],
'varyByRoute' => true, // 不同路由不同緩存
'varyByParam' => ['cat_id'], // 不同參數不同緩存
'varyBySession' => true, // 不同用戶不同緩存
'requestTypes' => ['GET'], // 僅 GET 請求緩存
])) { ?>
widget('CategoryMenu'); ?>
renderPartial('_ad_banner'); ?>
endCache(); } ?>
| 選項 | 類型 | 說明 |
|---|---|---|
| duration | integer | 有效秒數,0=永久,默認 60 |
| dependency | mixed | 依賴對象或配置陣列 |
| varyByRoute | boolean | 按路由變化 (控制器/動作) |
| varyByParam | array | 按 GET 參數變化 (如 ['id', 'cat']) |
| varyBySession | boolean | 按 Session ID 變化 |
| varyByExpression | string | 按 PHP 表達式結果變化 (1.0.4+) |
| requestTypes | array | 啟用緩存的請求類型 (默認 ['GET']) |
beginCache('page', ['duration' => 3600])) { ?>
renderPartial('_header'); ?>
beginCache('content', ['duration' => 1800])) { ?>
renderPartial('_articles'); ?>
endCache(); } ?>
endCache(); } ?>
原則:外層緩存失效時內層仍可命中;內層失效不影響外層 (外層仍服務舊副本)。
使用 COutputCache 作為動作過濾器:
// 控制器中
public function filters() {
return [
[
'COutputCache',
'duration' => 100,
'varyByParam' => ['id'],
// 'varyByRoute' => true,
// 'dependency' => [...],
],
];
}
// 或針對單個動作
public function filters() {
return [
'cache + index, view', // 僅 index、view 動作
[
'COutputCache',
'duration' => 3600,
'varyByParam' => ['id'],
],
];
}
原理:COutputCache 繼承 CFilterWidget,在 filter() (動作前) 檢查緩存,命中則直接輸出並 Yii::app()->end();未命中則啟用輸出緩衝,動作結束時捕獲內容存入緩存。
頁面大部分靜態,僅少量區塊 (如用戶名、購物車數量) 需動態:
beginCache('page', ['duration' => 3600])) { ?>
歡迎,renderDynamic('renderUserName'); ?>
購物車:renderDynamic(['CartWidget', 'getCount']); ?>
...靜態內容...
endCache(); } ?>
控制器實現回調:
public function renderUserName() {
return Yii::app()->user->isGuest ? '遊客' : Yii::app()->user->name;
}
// 或帶參數
public function renderUserProfile($uid) {
return User::model()->findByPk($uid)->name;
}
// 視圖中:$this->renderDynamic('renderUserProfile', $uid);
關鍵點:回調必須 返回字符串 而非直接輸出,每次請求都會執行回調並將結果插入緩存內容中。
CFileCache/CApcCache;分佈式 CMemCache/CRedisCache (Yii 2 原生/擴展)CDbCacheDependency 監聽核心表 MAX(updated_at)prefix:module:action:params_hash,避免衝突、便於批量清理Yii::app()->cache->getStats() (Memcache/APC 支持) 監控 hit/miss ratio,目標 > 90%Yii 1.1 緩存系統以 統一介面、多後端支援、豐富依賴機制、片段/頁面/動態三層緩存 構建了完整的性能優化體系。實戰中遵循「數據層緩存對象、視圖層緩存片段、頁面層緩存輸出、動態內容精準繞過」的分級策略,配合依賴驅動智能失效,可將響應時間從秒級壓縮至毫秒級,支撐高併發訪問。理解這套機制,遷移至 Yii 2 yii\caching 或 Laravel Cache 將毫無障礙。