編程學習網 > PHP技術 > Yii1 > Yii的緩存使用詳細教程
2014
11-11

Yii的緩存使用詳細教程

├──CApcCache.php

├──CCache.php

├──CDbCache.php

├──CDummyCache.php

├──CEAcceleratorCache.php

├──CFileCache.php

├──CMemCache.php

├──CWinCache.php

├──CXCache.php

├──CZendDataCache.php

└──dependencies

├──CCacheDependency.php

├──CChainedCacheDependency.php

├──CDbCacheDependency.php

├──CDirectoryCacheDependency.php

├──CExpressionDependency.php

├──CFileCacheDependency.php

└──CGlobalStateCacheDependency.php

1 directory, 17 files

Yii提供了不同的緩存組件,可以將緩存數據存儲到不同的媒介中。例如,CMemCache組件封裝了PHP的memcache擴展并使用內存作為緩存存儲媒介。CApcCache組件封裝了PHP APC擴展;而CDbCache組件會將緩存的數據存入數據庫。下面是一個可用緩存組件的列表:

·CMemCache:使用PHP memcache擴展.

·CApcCache:使用PHP APC擴展.

·CXCache:使用PHP XCache擴展。注意,這個是從1.0.1版本開始支持的。

·CEAcceleratorCache:使用PHP EAccelerator擴展.

·CDbCache:使用一個數據表存儲緩存數據。默認情況下,它將創建并使用在runtime目錄下的一個SQLite3數據庫。你也可以通過設置其connectionID屬性指定一個給它使用的數據庫。

·CZendDataCache:使用Zend Data Cache作為后臺緩存媒介。注意,這個是從1.0.4版本開始支持的。

·CFileCache:使用文件存儲緩存數據。這個特別適合用于存儲大塊數據(例如頁面)。注意,這個是從1.0.6版本開始支持的。

·CDummyCache:目前dummy緩存并不實現緩存功能。此組件的目的是用于簡化那些需要檢查緩存可用性的代碼。例如,在開發階段或者服務器尚未支持實際的緩存功能,我們可以使用此緩存組件。當啟用了實際的緩存支持后,我們可以切換到使用相應的緩存組件。在這兩種情況中,我們可以使用同樣的代碼Yii::app()->cache->get($key)獲取數據片段而不需要擔心Yii::app()->cache可能會是null。此組件從1.0.5版開始支持。

提示:由于所有的這些緩存組件均繼承自同樣的基類CCache,因此無需改變使用緩存的那些代碼就可以切換到使用另一種緩存方式。

使用方式:

yii封裝了對不同緩存操作的方法,主要集中在CCache。CCache是所有Cache類的基類。所以配置好緩存后可以調用方式很簡單:

根據CCache類說明可以看出,常見的緩存操作方法get,set,add,delete,flush

使用多種緩存

main.php 的配置

‘cache’ => array (

‘class’ => ‘system.caching.CFileCache’

),

‘dbcache’ => array (

‘class’ => ‘system.caching.CDbCache’

)

控制器只需用相應的cacheid調用就好

如:Yii::app()->dbcache

memcached緩存的配置

1.下載memcached軟件包,解壓,把memcached.exe放到隨意一個地方,比如:d:/memcached/下。

2. .開始->運行->輸入cmd,命令行打開memcached.exe,所在文件夾,輸入:memcached.exe -d install 安裝

3.輸入memcached.exe -d start啟動

4.下載php_memcache.dll文件,放到php/ext/文件夾下,并在php.ini中加入extension=php_memcache.dll。

5.打開yii配置文件:config/main.php,在components下添加:

'memcache'=>array( 

       'class'=>'CMemCache', 

       'servers'=>array( 

           array( 

               'host'=>'127.0.0.1', 

               'port'=>11211, 

               'weight'=>60, 

           ), 

           array( 

               'host'=>'127.0.0.1', 

               'port'=>11211, 

               'weight'=>40, 

           ), 

        ), 

 ),

使用:

Yii::app()->memcache->get(id);

Yii::app()->memcache->set(id,value,time);

Yii::app()->cache->deleteValue($key);

一、數據緩存

$value=Yii::app()->cache->get($id);

if($value===false)

{

//因為在緩存中沒找到,重新生成$value

//再緩存一下以備下次使用

//Yii::app()->cache->set($id,$value);

}

為一個要緩存的變量選擇ID時,確保該ID在應用中是唯一的。不必保證ID在跨應用的情況下保證唯一,因為緩存組件有足夠的智能來區分不同應用的緩存ID。要從緩存中刪除一個緩存值,調用delete();要清空所有緩存,調用flush()。調用flush()時要非常小心,因為它會把其它應用的緩存也清空。提示:因為CCache實現了ArrayAccess接口,可以像數組一樣使用緩存組件。例如:

$cache=Yii::app()->cache;

$cache['var1']=$value1;//相當于:$cache->set('var1',$value1);

$value2=$cache['var2'];//相當于: $value2=$cache->get('var2');

緩存依賴除了過期設置,緩存數據還會因某些依賴條件發生改變而失效。如果我們緩存了某文件的內容,而該文件后來又被更新了,我們應該讓緩存中的拷貝失效,從文件中讀取最新內容(而不是從緩存)。我們把一個依賴關系表現為一個CCacheDependency或它的子類的實例,調用set()的時候把依賴實例和要緩存的數據一起傳入。//緩存將在30秒后過期//也可能因依賴的文件有更新而更快失效Yii::app()->cache->set($id, $value, 30, new CFileCacheDependency('FileName'));如果我們現在調用get()從緩存中獲取$value,緩存組件將檢查依賴條件。如果有變,我們會得到false值——數據需要重新生成。下面是可用的緩存依賴的簡要說明:CFileCacheDependency:該依賴因文件的最近修改時間發生改變而改變。CDirectoryCacheDependency:該依賴因目錄(或其子目錄)下的任何文件發生改變而改變。CDbCacheDependency:該依賴因指定的SQL語句的查詢結果發生改變而改變。CGlobalStateCacheDependency:該依賴因指定的全局狀態值發生改變而改變。全局狀態是應用中跨請求、跨SESSION的持久變量,它由CApplication::setGlobalState()來定義。CChainedCacheDependency:該依賴因依賴鏈中的任何一環發生改變而改變。

二、片段緩存  (Fragment Caching)

片段緩存指緩存網頁某片段。例如,如果一個頁面在表中顯示每年的銷售摘要,我們可以存儲此表在緩存中,減少每次請求需要重新產生的時間。要使用片段緩存,在控制器視圖腳本中調用CController::beginCache()和CController::endCache()。這兩種方法開始和結束包括的頁面內容將被緩存。類似data caching,我們需要一個編號,識別被緩存的片段。...別的HTML內容...

<?phpif($this->beginCache($id)) { ?>

...被緩存的內容...

<?php$this->endCache(); } ?>

...別的HTML內容...

在上面的,如果beginCache()返回false,緩存的內容將此地方自動插入;否則,在if語句內的內容將被執行并在endCache()觸發時緩存。

1.緩存選項(Caching Options)

當調用beginCache(),可以提供一個數組由緩存選項組成的作為第二個參數,以自定義片段緩存。事實上為了方便,beginCache()和endCache()方法是COutputCache widget的包裝。因此COutputCache的所有屬性都可以在緩存選項中初始化。

2.有效期(Duration)

也許是最常見的選項是duration,指定了內容在緩存中多久有效。和CCache::set()過期參數有點類似。下面的代碼緩存內容片段最多一小時:...其他HTML內容...<?phpif($this->beginCache($id, array('duration'=>3600))){ ?>

...被緩存的內容...

<?php$this->endCache(); } ?>...其他HTML內容...如果我們不設定期限,它將默認為60,這意味著60秒后緩存內容將無效。

3.依賴(Dependency)

像data caching,內容片段被緩存也可以有依賴。例如,文章的內容被顯示取決于文章是否被修改。要指定一個依賴,我們建立了dependency選項,可以是一個實現ICacheDependency的對象或可用于生成依賴對象的配置數組。下面的代碼指定片段內容取決lastModified列的值是否變化:...其他HTML內容...

<?php if($this->beginCache($id, array('dependency'=>array(

'class'=>'system.caching.dependencies.CDbCacheDependency',

'sql'=>'SELECT MAX(lastModified) FROM Post')))) { ?>

...被緩存的內容 ...

<?php $this->endCache(); } ?>

...其他 HTML 內容 ...

4.變化(Variation)

緩存的內容可根據一些參數變化。例如,每個人的檔案都不一樣。緩存的檔案內容將根據每個人ID變化。這意味著,當調用beginCache()時將用不同的ID。COutputCache內置了這一特征,程序員不需要編寫根據ID變動內容的模式。以下是摘要。varyByRoute:設置此選項為true,緩存的內容將根據route變化。因此,每個控制器和行動的組合將有一個單獨的緩存內容。varyBySession:設置此選項為true,緩存的內容將根據sessionID變化。因此,每個用戶會話可能會看到由緩存提供的不同內容。varyByParam:設置此選項的數組里的名字,緩存的內容將根據GET參數的值變動。例如,如果一個頁面顯示文章的內容根據id的GET參數,我們可以指定varyByParam為array('id'),以使我們能夠緩存每篇文章內容。如果沒有這樣的變化,我們只能能夠緩存某一文章。這里有問題要討論:我可以正確使用以下數據調用

if($this->beginCache('good_list_manager',array('duration'=>3600,'varyByParam'=>array('id')))){?>

{

    // ... display the content to be cachedhere

   $this->endCache();

}

但是以下代碼不能使用,因為其參數為‘Goods[name]’YII無法正確識別!

if($this->beginCache('good_list_manager',array('duration'=>3600,'varyByParam'=>array("Goods[name]")))

{

    // ... display the content to be cachedhere

   $this->endCache();

}

解決方法:自己建立根據ID變動內容的模式。

if($this->beginCache('good_list_manager_'.$_GET[Goods][name].'_'.$_GET[Goods][bn].'_'.$_GET[Goods][cat_id].'_'.$_GET[Goods][brand_id].'_'.$_GET[Goods][marketable].'_'.$_GET[Goods][cps_status].'_'.$_GET[Goods][is_check],array('duration'=>3600))){?>

{

    // ... display the content to be cachedhere

   $this->endCache();

}

5.請求類型(Request Types)

有時候,我們希望片段緩存只對某些類型的請求啟用。例如,對于某張網頁上顯示表單,我們只想要緩存initiallyrequested表單(通過GET請求)。任何隨后顯示(通過POST請求)的表單將不被緩存,因為表單可能包含用戶輸入。要做到這一點,我們可以指定requestTypes選項:

...其他HTML內容...

<?php if($this->beginCache($id,array('requestTypes'=>array('GET')))) { ?>

...被緩存的內容...

<?php $this->endCache(); } ?>

...其他HTML內容...

6.嵌套緩存(Nested Caching)

片段緩存可以嵌套。就是說一個緩存片段附在一個更大的片段緩存里。例如,意見緩存在內部片段緩存,而且它們一起在外部緩存中在文章內容里緩存。

...其他HTML內容...

<?php if($this->beginCache($id1)) { ?>

...外部被緩存內容...

<?php if($this->beginCache($id2)) { ?>

...內部被緩存內容...

<?php $this->endCache(); } ?>

...外部被緩存內容...

<?php $this->endCache(); } ?>

...其他HTML內容...

嵌套緩存可以設定不同的緩存選項。例如,在上面的例子中內部緩存和外部緩存可以設置時間長短不同的持續值。當數據存儲在外部緩存無效,內部緩存仍然可以提供有效的內部片段。然而,反之就不行了。如果外部緩存包含有效的數據,它會永遠保持緩存副本,即使內容中的內部緩存已經過期。

三、頁面緩存

頁面緩存指的是緩存整個頁面的內容。頁面緩存可以發生在不同的地方。例如,通過選擇適當的頁面頭,客戶端的瀏覽器可能會緩存網頁瀏覽有限時間。Web應用程序本身也可以在緩存中存儲網頁內容。在本節中,我們側重于后一種辦法。頁面緩存可以被看作是片段緩存(/doc/guide/caching.fragment)一個特殊情況。由于網頁內容是往往通過應用布局來生成,如果我們只是簡單的在布局中調用beginCache()和endCache(),將無法正常工作。這是因為布局在CController::render()方法里的加載是在頁面內容產生之后。緩存整個頁面,我們應該跳過產生網頁內容的動作執行。我們可以使用COutputCache作為動作過濾器(/doc/guide/basics.controller#filter)來完成這一任務。下面的代碼演示如何配置緩存過濾器:

public function filters()

{

return array(

array(

'system.web.widgets.COutputCache',

'duration'=>100,

'varyByParam'=>array('id'),

),

);

}

上述過濾器配置會使過濾器適用于控制器中的所有行動。我們可能會限制它在一個或幾個行動通過使用插件操作器。更多的細節中可以看過濾器(/doc/guide/basics.controller#filter)。提示:我們可以使用COutputCache作為一個過濾器,因為它從CFilterWidget繼承過來,這意味著它是一個工具(widget)和一個過濾器。事實上,widge的工作方式和過濾器非常相似:工具widget (過濾器filter)是在action動作里的內容執行前執行,在執行后結束。

四、動態內容(DynamicContent)

當使用fragment caching或page caching,我們常常遇到的這樣的情況整個部分的輸出除了個別地方都是靜態的。例如,幫助頁可能會顯示靜態的幫助信息,而用戶名稱顯示的是當前用戶的。解決這個問題,我們可以根據用戶名匹配緩存內容,但是這將是我們寶貴空間一個巨大的浪費,因為緩存除了用戶名其他大部分內容是相同的。我們還可以把網頁切成幾個片段并分別緩存,但這種情況會使頁面和代碼變得非常復雜。更好的方法是使用由CController提供的動態內容dynamic content功能。動態內容是指片段輸出即使是在片段緩存包括的內容中也不會被緩存。即使是包括的內容是從緩存中取出,為了使動態內容在所有時間是動態的,每次都得重新生成。出于這個原因,我們要求動態內容通過一些方法或函數生成。調用CController::renderDynamic()在你想的地方插入動態內容。

...別的HTML內容...

<?phpif($this->beginCache($id)) { ?>

...被緩存的片段內容...

<?php$this->renderDynamic($callback); ?>

...被緩存的片段內容...

<?php$this->endCache(); } ?>

...別的HTML內容...

renderDynamic復雜調用形式:$this->renderDynamic('widget','application.extensions.uinfo',array('uid'=>'hahahah!'),true);就相當于$this->widget('application.extensions.uinfo',array('uid'=>'hahahah!'),true);在上面的,$callback指的是有效的PHP回調。它可以是指向當前控制器類的方法或者全局函數的字符串名。它也可以是一個數組名指向一個類的方法。其他任何的參數,將傳遞到renderDynamic()方法中?;卣{將返回動態內容而不是僅僅顯示它。

掃碼二維碼 獲取免費視頻學習資料

Python編程學習

查 看2022高級編程視頻教程免費獲取