## Yii2數據緩存
[TOC]
### 增刪改查
在日常開發中最長用的是對緩存數據的增刪改查,具體操作如下:
```
$cache = \Yii::$app->cache;
$cache->add('keyName',$keyVal); // 新增緩存數據
$cache->delete('keyName'); // 刪除緩存數據
$cache->set('keyName',$newVal); // 修改緩存數據
$cache->get('keyName'); // 獲取緩存數據
$cache->flush(); //清空緩存
```
### 緩存其他配置
#### 緩存有效期
```
$cache = \Yii::$app->cache
$cache->add('keyName',$keyVal,10); // 新增緩存數據10秒有效
$cache->set('keyName',$keyVal,10); // 設置緩存數據10秒有效
```
### 緩存依賴關系
Yii提供了5中依賴方法,Yii中的緩存依賴,簡單來說就是將緩存和另外一個東西綁定在一起,如果另外一個東西發生變化,那么緩存也將發生變化,緩存的變動是依賴的東西所導致的。
依賴可以是文件、數據庫、甚至是一些表達式,功能十分強大。
#### 文件依賴
顧名思義,緩存除了可以設置有效期可能需要依賴文件,假如我們傳入的文件在存儲緩存時發生了改變即文件最后修改的時間戳發生了改變,那么將導致緩存失效。
```
$cache = Yii::$app->cache;
// 文件依賴
$dependency = new \yii\caching\FileDependency(['fileName' => 'test.txt']);
// $cache->add('file_key','hello world!',100,$dependency);
var_dump($cache->get('file_key'));
```
> 上述文件依賴配置中所依賴的文件名是`test.txt` ,我們需要創建一個文件名為`test.txt`在項目根目錄下。在修改文件前先運行新增緩存數據操作,然后修改`test.txt`依賴文件后再訪問緩存數據返回`false`。
#### 表達式依賴
通過接收地址欄的參數進行緩存數據的依賴處理,如下:
```
$cache = Yii::$app->cache;
// 表達式依賴
$dependency = new \yii\caching\ExpressionDependency(
['expression' => '\Yii::$app->request->get("name")']
);
// $cache->add('expression_key', 'hello world!', 100, $dependency);
var_dump($cache->get('expression_key'));
```
> 上述**表達式依賴**假如我們在新增緩存數據時候訪問的地址傳遞參數`name`值為`hello`,那么我們在下次訪問的時候也需要使用`&name=hello`的方式傳遞表達式依賴進行緩存的讀取,或者過期時間到了沒有再次寫入數據到緩存,都將返回`false`。
#### 數據庫依賴
使用對數據庫數據的依賴,我們可以很方便的定義一個sql進行數據庫的查詢,如果數據庫查詢條件和上次不符,那么緩存將失敗。
```
$cache = Yii::$app->cache;
// DB依賴
$dependency = new \yii\caching\DbDependency(
['sql' => 'SELECT COUNT(*) FROM user']
);
// $cache->add('db_key', 'hello world!', 100, $dependency);
var_dump($cache->get('db_key'));
```
> 假如我們當前的項目連接的庫下有一個`user`表,那么我們統計表內總共的數據條數,在100秒的緩存有效期內如果數據總量進行了修改,那么緩存將失效,將返回`false`。
#### 鏈式依賴
鏈式依賴指我們可以把多個依賴關系傳遞給一個依賴,任何一個發生變化都會使緩存失效。
```php
$cache = Yii::$app->cache;
//表達式依賴
$dp1 = new \yii\caching\ExpressionDependency([
'expression' => 'count(\Yii::$app->authManager->getPermissionsByUser(Yii::$app->user->id))'
]);
// DB依賴
$dp2 = new \yii\caching\DbDependency(
['sql' => 'SELECT COUNT(*) FROM user']
);
$cache->set($key, $value, 0, new \yii\caching\ChainedDependencyChainedDependency([
'dependencies' => [$dp, $dp2]
]));
```
> 上面的兩個依賴關系中只要有一個依賴參數發生變化,緩存數據將失效返回`fasle`。
### 片段緩存
片段緩存指的是緩存頁面內容中的某個片段。我們可以緩存一段頁面在我們想存儲的介質中,而不用實時的去查詢數據庫獲取數據。
```php
<?php
// 緩存時間
// $duration = 50;
// 緩存依賴(以文件依賴為例,類似與上面的數據依賴)
$dependency = [
'class' => 'yii\caching\FileDependency',
'fileName' => 'test.txt'
];
// 緩存開關 false 為不開啟片段緩存
$enabled = false;
?>
<?php if ($this->beginCache('cacheKey', ['duration' => $duration,'dependency' => $dependency, 'enabled' => $enabled])) { ?>
<div id="cache_div">
<p>數據被緩存1113322332</p>
</div>
<?php $this->endCache();
} ?>
<div id="no_cache_div">
<p>數據不被緩存222</p>
</div>
```
> 我們使用視圖中的`beginCache()`和`endCache()`進行緩存片段的操作,同時也可以傳遞一些參數進行更多的定制操作。
#### 片段緩存的嵌套使用
```
<?php if ($this->beginCache('cacheKey', ['duration' => 20])) { ?>
<div id="cache_div">
<p>數據被緩存</p>
<?php if ($this->beginCache('cacheInnerKey', ['duration' => 10])) { ?>
<div id="inner_cache_div">
<p>嵌套緩存,被緩存</p>
</div>
<?php $this->endCache();
} ?>
</div>
<?php $this->endCache();
} ?>
```
> 如上嵌套緩存代碼,在使用的時候需要主要防止內層的緩存時間需要大于外層的嵌套緩存,因為如果外層的緩存時間沒有到期而內層的緩存到期了也不會重新去加載內層數據,因為外層數據被緩存。
### 頁面緩存
頁面緩存指的是在服務器端緩存整個頁面的內容。隨后當同一個頁面 被請求時,內容將從緩存中取出,而不是重新生成。
頁面緩存由 `yii\filters\PageCache` 類提供支持,該類是一個 過濾器。它可以像這樣在控制器類中使用:
```
public function behaviors()
{
return [
'pageCache' => [
'class' => 'yii\filters\PageCache',
'only' => ['index'], // 僅緩存index方法
'duration' => 60, // 頁面緩存60秒
'variations' => [
\Yii::$app->language,
],
'dependency' => [ // 緩存依賴
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT COUNT(*) FROM user',
],
],
];
}
```
頁面緩存和[片段緩存](http://www.yiichina.com/doc/guide/2.0/caching-fragment)極其相似。它們都支持?`duration`,`dependencies`,?`variations`?和?`enabled`?配置選項。它們的主要區別是頁面緩存是由[過濾器](http://www.yiichina.com/doc/guide/2.0/structure-filters)實現, 而片段緩存則是一個[小部件](http://www.yiichina.com/doc/guide/2.0/structure-widgets)。
### HTTP緩存
通過配置 `yii\filters\HttpCache` 過濾器,控制器操作渲染的內容就能緩存在客戶端。`yii\filters\HttpCache` 過濾器僅對?`GET`?和?`HEAD`?請求生效,它能為這些請求設置三種與緩存有關的 HTTP 頭。
* yii\filters\HttpCache::lastModified
* yii\filters\HttpCache::etagSeed
* yii\filters\HttpCache::cacheControlHeader
```
public function behaviors()
{
return [
[
'class' => HttpCache::className(),
'only' => ['view'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('post')->max('updated_at');
},
'etagSeed' => function ($action, $params) {
$post = $this->findModel(\Yii::$app->request->get('id'));
return serialize([$post->title, $post->content]);
},
]
];
}
```
具體請[參見官方文檔](http://www.yiichina.com/doc/guide/2.0/caching-http)。
- 開始
- Yii2開發小技巧
- Yii2使用不同的方式進行郵件發送邏輯處理
- Yii2 Serialization of 'Closure' is not allowed 錯誤
- Yii創建應用
- Yii應用結構和流程
- Yii的路徑別名
- Yii的請求
- Yii的響應
- Sessions 和 Cookies
- Yii自定義全局工具函數
- Yii2模型
- Yii2視圖
- Yii2控制器
- 大數據節省內存處理
- 關聯查詢hasMany、hasOne
- Yii2 URL地址美化
- Yii2整合AdminLTE后臺主題
- Yii2模型中的場景
- Yii2中的RBAC
- Yii2項目后臺整合yii2-admin模塊
- RBAC集成AdminLTE后臺主題對菜單進行控制
- Yii2自定義Gii模板
- 修復AdminLTE引用外部字體文件導致訪問變慢的情況
- Yii2事件簡單使用
- Yii2模型事件
- Yii2使用GridView新增操作按鈕
- Yii2向loyout模板文件中傳值
- Yii2數據緩存
- Yii2緩存
- Yii2數據緩存之增刪改查
- Yii2拓展
- Yii2日期時間插件-datetimepicker
- kartik-v/yii2-widget-fileinput上傳插件