Detailed explanation of cache usage in YII Framework framework tutorial
Dec 27, 2016 pm 02:04 PMThe example in this article describes the usage of YII Framework framework cache. Share it with everyone for your reference, the details are as follows:
The reasons for caching are well known. Therefore, as an efficient and easy-to-use framework, YII cannot but support caching. Therefore, YII provides interfaces for various popular caches, and you can use different caches according to your needs.
1.Introduction to caching in YII
The cache in YII is defined through components, specifically in the following directory
/yii_dev/yii/framework/caching# tree
.
├── CApcCache.php
├── CCache.php
├── CDbCache.php
├── CDummyCache.php
├── CEAcceleratorCache.php
├── CFileCache.php
├── CMemCache.php
├── CWinCache.php
├── CXCache.php
├── CZendDataCache.php
└── dependencies
├── CCacheDependency.php
├── CCacheDependency.php
├── CDbCacheDependency.php
├── CDirectoryCacheDependency.php
├── CExpressionDependency.php
├ ── CFileCacheDependency.php
└── CGlobalStateCacheDependency.php
1 directory, 17 files
The official original text is explained as follows:
Yii provides different caching components, Cache data can be stored on different media. For example, the CMemCache component encapsulates PHP's memcache extension and uses memory as the cache storage medium. The CApcCache component encapsulates the PHP APC extension; and the CDbCache component stores cached data in the database. Here is a list of available caching components:
CMemCache: Uses the PHP memcache extension.
CApcCache: Uses the PHP APC extension.
CXCache: Uses the PHP XCache extension. Note that this is supported starting from version 1.0.1.
CEAcceleratorCache: Use PHP EAccelerator extension.
CDbCache: Use a data table to store cache data. By default, it will create and use a SQLite3 database in the runtime directory. You can also specify a database for it to use by setting its connectionID property.
CZendDataCache: Use Zend Data Cache as the backend caching medium. Note that this is supported starting from version 1.0.4.
CFileCache: Use files to store cache data. This is particularly useful for storing large chunks of data (such as pages). Note that this is supported starting from version 1.0.6.
CDummyCache: Currently dummy cache does not implement caching function. The purpose of this component is to simplify code that needs to check cache availability. For example, we can use this caching component during the development phase or when the server does not yet support actual caching functionality. When actual caching support is enabled, we can switch to using the corresponding caching component. In both cases, we can use the same code Yii::app()->cache->get($key) to get the data fragment without worrying that Yii::app()->cache may is null. This component is supported since version 1.0.5.
Tip: Since all these caching components inherit from the same base class CCache, you can switch to using another caching method without changing the code that uses the cache.
Caching can be used at different levels. At the lowest level, we use caches to store individual pieces of data, such as variables. We call this data caching. At the next level, we store in the cache a page fragment generated as part of the view script. And in the highest level, we store the entire page in cache and retrieve it when needed.
In the next few sections, we will explain in detail how to use caching at these levels.
Note: By definition, a cache is an unstable storage medium. Even if there is no timeout, it does not ensure that the cached data will exist. Therefore, do not use cache as persistent storage. (For example, do not use cache to store Session data).
2. Cache configuration and calling method
The cache in yii is mainly implemented through components. The specific configuration method can be configured through the cache class description.
Usually the class that specifies the cache component
For example, apc
'cache'=>array( 'class'=>'system.caching.CApcCache' ),
The configuration method of memcache may be
* array( * 'components'=>array( * 'cache'=>array( * 'class'=>'CMemCache', * 'servers'=>array( * array( * 'host'=>'server1', * 'port'=>11211, * 'weight'=>60, * ), * array( * 'host'=>'server2', * 'port'=>11211, * 'weight'=>40, * ), * ), * ), * ), * )
Usage method:
Yii encapsulates methods for different cache operations, mainly focusing on CCache. CCache is the base class for all Cache classes. Therefore, the calling method after configuring the cache is very simple:
<?php /** * CCache is the base class for cache classes with different cache storage implementation. * * A data item can be stored in cache by calling {@link set} and be retrieved back * later by {@link get}. In both operations, a key identifying the data item is required. * An expiration time and/or a dependency can also be specified when calling {@link set}. * If the data item expires or the dependency changes, calling {@link get} will not * return back the data item. * * Note, by definition, cache does not ensure the existence of a value * even if it does not expire. Cache is not meant to be a persistent storage. * * CCache implements the interface {@link ICache} with the following methods: * <ul> * <li>{@link get} : retrieve the value with a key (if any) from cache</li> * <li>{@link set} : store the value with a key into cache</li> * <li>{@link add} : store the value only if cache does not have this key</li> * <li>{@link delete} : delete the value with the specified key from cache</li> * <li>{@link flush} : delete all values from cache</li> * </ul> * * Child classes must implement the following methods: * <ul> * <li>{@link getValue}</li> * <li>{@link setValue}</li> * <li>{@link addValue}</li> * <li>{@link deleteValue}</li> * <li>{@link flush} (optional)</li> * </ul> * * CCache also implements ArrayAccess so that it can be used like an array. * * @author Qiang Xue <qiang.xue@gmail.com> * @version $Id: CCache.php 3001 2011-02-24 16:42:44Z alexander.makarow $ * @package system.caching * @since 1.0 */ abstract class CCache extends CApplicationComponent implements ICache, ArrayAccess {
According to the CCache class description, it can be seen that the common cache operation methods get, set, add, delete, flush
/** * Retrieves a value from cache with a specified key. * @param string $id a key identifying the cached value * @return mixed the value stored in cache, false if the value is not in the cache, expired or the dependency has changed. */ public function get($id) { if(($value=$this->getValue($this->generateUniqueKey($id)))!==false) { $data=unserialize($value); if(!is_array($data)) return false; if(!($data[1] instanceof ICacheDependency) || !$data[1]->getHasChanged()) { Yii::trace('Serving "'.$id.'" from cache','system.caching.'.get_class($this)); return $data[0]; } } return false; } /** * Retrieves multiple values from cache with the specified keys. * Some caches (such as memcache, apc) allow retrieving multiple cached values at one time, * which may improve the performance since it reduces the communication cost. * In case a cache doesn't support this feature natively, it will be simulated by this method. * @param array $ids list of keys identifying the cached values * @return array list of cached values corresponding to the specified keys. The array * is returned in terms of (key,value) pairs. * If a value is not cached or expired, the corresponding array value will be false. * @since 1.0.8 */ public function mget($ids) { $uniqueIDs=array(); $results=array(); foreach($ids as $id) { $uniqueIDs[$id]=$this->generateUniqueKey($id); $results[$id]=false; } $values=$this->getValues($uniqueIDs); foreach($uniqueIDs as $id=>$uniqueID) { if(!isset($values[$uniqueID])) continue; $data=unserialize($values[$uniqueID]); if(is_array($data) && (!($data[1] instanceof ICacheDependency) || !$data[1]->getHasChanged())) { Yii::trace('Serving "'.$id.'" from cache','system.caching.'.get_class($this)); $results[$id]=$data[0]; } } return $results; } /** * Stores a value identified by a key into cache. * If the cache already contains such a key, the existing value and * expiration time will be replaced with the new ones. * * @param string $id the key identifying the value to be cached * @param mixed $value the value to be cached * @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. * @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid. * @return boolean true if the value is successfully stored into cache, false otherwise */ public function set($id,$value,$expire=0,$dependency=null) { Yii::trace('Saving "'.$id.'" to cache','system.caching.'.get_class($this)); if($dependency!==null) $dependency->evaluateDependency(); $data=array($value,$dependency); return $this->setValue($this->generateUniqueKey($id),serialize($data),$expire); } /** * Stores a value identified by a key into cache if the cache does not contain this key. * Nothing will be done if the cache already contains the key. * @param string $id the key identifying the value to be cached * @param mixed $value the value to be cached * @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. * @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid. * @return boolean true if the value is successfully stored into cache, false otherwise */ public function add($id,$value,$expire=0,$dependency=null) { Yii::trace('Adding "'.$id.'" to cache','system.caching.'.get_class($this)); if($dependency!==null) $dependency->evaluateDependency(); $data=array($value,$dependency); return $this->addValue($this->generateUniqueKey($id),serialize($data),$expire); } /** * Deletes a value with the specified key from cache * @param string $id the key of the value to be deleted * @return boolean if no error happens during deletion */ public function delete($id) { Yii::trace('Deleting "'.$id.'" from cache','system.caching.'.get_class($this)); return $this->deleteValue($this->generateUniqueKey($id)); } /** * Deletes all values from cache. * Be careful of performing this operation if the cache is shared by multiple applications. * @return boolean whether the flush operation was successful. */ public function flush() { Yii::trace('Flushing cache','system.caching.'.get_class($this)); return $this->flushValues(); }
are:
Yii::app()->cache->xxx
xxx corresponds to the specific method.
For example:
$id = 'key1'; $value = 'cache value'; Yii::app()->cache->add($id, $value); var_dump(Yii::app()->cache->get($id));
The following are the instructions for using several caching methods officially given by Yii. It is insensitive and copied here
3. Cache usage: data caching
Data caching
Data caching stores some PHP variables in the cache and then retrieves them from the cache later. For this purpose, the cache component's base class CCache provides the two most commonly used methods: set() and get().
To store a variable $value in the cache, we choose a unique ID and call set() to store it:
Yii::app()->cache->set($id, $value);
緩存的數(shù)據(jù)將一直留在緩存中,除非它由于某些緩存策略(例如緩存空間已滿,舊的數(shù)據(jù)被刪除)而被清除。 要改變這種行為,我們可以在調(diào)用 set() 的同時提供一個過期參數(shù),這樣在設(shè)定的時間段之后,緩存數(shù)據(jù)將被清除:
// 值$value 在緩存中最多保留30秒 Yii::app()->cache->set($id, $value, 30);
稍后當(dāng)我們需要訪問此變量時(在同一個或不同的 Web 請求中),就可以通過 ID 調(diào)用 get() 從緩存中將其取回。 如果返回的是 false,表示此值在緩存中不可用,我們應(yīng)該重新生成它。
$value=Yii::app()->cache->get($id); if($value===false) { // 因為在緩存中沒找到 $value ,重新生成它 , // 并將它存入緩存以備以后使用: // Yii::app()->cache->set($id,$value); }
為要存入緩存的變量選擇 ID 時,要確保此 ID 對應(yīng)用中所有其他存入緩存的變量是唯一的。 而在不同的應(yīng)用之間,這個 ID 不需要是唯一的。緩存組件具有足夠的智慧區(qū)分不同應(yīng)用中的 ID。
一些緩存存儲器,例如 MemCache, APC, 支持以批量模式獲取多個緩存值。這可以減少獲取緩存數(shù)據(jù)時帶來的開銷。 從版本 1.0.8 起,Yii 提供了一個新的名為 mget() 的方法。它可以利用此功能。如果底層緩存存儲器不支持此功能,mget() 依然可以模擬實現(xiàn)它。
要從緩存中清除一個緩存值,調(diào)用 delete(); 要清楚緩存中的所有數(shù)據(jù),調(diào)用 flush()。 當(dāng)調(diào)用 flush() 時一定要小心,因為它會同時清除其他應(yīng)用中的緩存。
提示: 由于 CCache 實現(xiàn)了 ArrayAccess,緩存組件也可以像一個數(shù)組一樣使用。下面是幾個例子:
$cache=Yii::app()->cache; $cache['var1']=$value1; // 相當(dāng)于: $cache->set('var1',$value1); $value2=$cache['var2']; // 相當(dāng)于: $value2=$cache->get('var2');
1. 緩存依賴
除了過期設(shè)置,緩存數(shù)據(jù)也可能會因為依賴條件發(fā)生變化而失效。例如,如果我們緩存了某些文件的內(nèi)容,而這些文件發(fā)生了改變,我們就應(yīng)該讓緩存的數(shù)據(jù)失效, 并從文件中讀取最新內(nèi)容而不是從緩存中讀取。
我們將一個依賴關(guān)系表現(xiàn)為一個 CCacheDependency 或其子類的實例。 當(dāng)調(diào)用 set() 時,我們連同要緩存的數(shù)據(jù)將其一同傳入。
// 此值將在30秒后失效 // 也可能因依賴的文件發(fā)生了變化而更快失效 Yii::app()->cache->set($id, $value, 30, new CFileCacheDependency('FileName'));
現(xiàn)在如果我們通過調(diào)用get() 從緩存中獲取 $value ,依賴關(guān)系將被檢查,如果發(fā)生改變,我們將會得到一個 false 值,表示數(shù)據(jù)需要被重新生成。
如下是可用的緩存依賴的簡要說明:
CFileCacheDependency: 如果文件的最后修改時間發(fā)生改變,則依賴改變。
CDirectoryCacheDependency: 如果目錄和其子目錄中的文件發(fā)生改變,則依賴改變。
CDbCacheDependency: 如果指定 SQL 語句的查詢結(jié)果發(fā)生改變,則依賴改變。
CGlobalStateCacheDependency: 如果指定的全局狀態(tài)發(fā)生改變,則依賴改變。全局狀態(tài)是應(yīng)用中的一個跨請求,跨會話的變量。它是通過 CApplication::setGlobalState() 定義的。
CChainedCacheDependency: 如果鏈中的任何依賴發(fā)生改變,則此依賴改變。
CExpressionDependency: 如果指定的 PHP 表達(dá)式的結(jié)果發(fā)生改變,則依賴改變。此類從版本 1.0.4 起可用。
4.緩存的使用:片段緩存
片段緩存(Fragment Caching)
片段緩存指緩存網(wǎng)頁某片段。例如,如果一個頁面在表中顯示每年的銷售摘要,我們可以存儲此表在緩存中,減少每次請求需要重新產(chǎn)生的時間。
要使用片段緩存,在控制器視圖腳本中調(diào)用CController::beginCache() 和CController::endCache() 。這兩種方法開始和結(jié)束包括的頁面內(nèi)容將被緩存。類似data caching ,我們需要一個編號,識別被緩存的片段。
...別的HTML內(nèi)容... <?php if($this->beginCache($id)) { ?> ...被緩存的內(nèi)容... <?php $this->endCache(); } ?> ...別的HTML內(nèi)容...
如果我們不設(shè)定期限,它將默認(rèn)為60 ,這意味著60秒后緩存內(nèi)容將無效。
依賴(Dependency)
像data caching ,內(nèi)容片段被緩存也可以有依賴。例如,文章的內(nèi)容被顯示取決于文章是否被修改。
要指定一個依賴,我們建立了dependency選項,可以是一個實現(xiàn)[ICacheDependency]的對象或可用于生成依賴對象的配置數(shù)組。下面的代碼指定片段內(nèi)容取決于lastModified 列的值是否變化:
...其他HTML內(nèi)容... <?php if($this->beginCache($id, array('dependency'=>array( 'class'=>'system.caching.dependencies.CDbCacheDependency', 'sql'=>'SELECT MAX(lastModified) FROM Post')))) { ?> ...被緩存的內(nèi)容... <?php $this->endCache(); } ?> ...其他HTML內(nèi)容...
變化(Variation)
緩存的內(nèi)容可根據(jù)一些參數(shù)變化。例如,每個人的檔案都不一樣。緩存的檔案內(nèi)容將根據(jù)每個人ID變化。這意味著,當(dāng)調(diào)用beginCache()時將用不同的ID。
COutputCache內(nèi)置了這一特征,程序員不需要編寫根據(jù)ID變動內(nèi)容的模式。以下是摘要。
varyByRoute: 設(shè)置此選項為true ,緩存的內(nèi)容將根據(jù)route變化。因此,每個控制器和行動的組合將有一個單獨的緩存內(nèi)容。
varyBySession: 設(shè)置此選項為true ,緩存的內(nèi)容將根據(jù)session ID變化。因此,每個用戶會話可能會看到由緩存提供的不同內(nèi)容。
varyByParam: 設(shè)置此選項的數(shù)組里的名字,緩存的內(nèi)容將根據(jù)GET參數(shù)的值變動。例如,如果一個頁面顯示文章的內(nèi)容根據(jù)id的GET參數(shù),我們可以指定varyByParam為array('id'),以使我們能夠緩存每篇文章內(nèi)容。如果沒有這樣的變化,我們只能能夠緩存某一文章。
varyByExpression: by setting this option to a PHP expression, we can make the cached content to be variated according to the result of this PHP expression. This option has been available since version 1.0.4.
Request Types
有時候,我們希望片段緩存只對某些類型的請求啟用。例如,對于某張網(wǎng)頁上顯示表單,我們只想要緩存initially requested表單(通過GET請求)。任何隨后顯示(通過POST請求)的表單將不被緩存,因為表單可能包含用戶輸入。要做到這一點,我們可以指定requestTypes 選項:
...其他HTML內(nèi)容... <?php if($this->beginCache($id, array('requestTypes'=>array('GET')))) { ?> ...被緩存的內(nèi)容... <?php $this->endCache(); } ?> ...其他HTML內(nèi)容...
2. 嵌套緩存(Nested Caching)
片段緩存可以嵌套。就是說一個緩存片段附在一個更大的片段緩存里。例如,意見緩存在內(nèi)部片段緩存,而且它們一起在外部緩存中在文章內(nèi)容里緩存。
...其他HTML內(nèi)容... <?php if($this->beginCache($id1)) { ?> ...外部被緩存內(nèi)容... <?php if($this->beginCache($id2)) { ?> ...內(nèi)部被緩存內(nèi)容... <?php $this->endCache(); } ?> ...外部被緩存內(nèi)容... <?php $this->endCache(); } ?> ...其他HTML內(nèi)容...
嵌套緩存可以設(shè)定不同的緩存選項。例如, 在上面的例子中內(nèi)部緩存和外部緩存可以設(shè)置時間長短不同的持續(xù)值。當(dāng)數(shù)據(jù)存儲在外部緩存無效,內(nèi)部緩存仍然可以提供有效的內(nèi)部片段。 然而,反之就不行了。如果外部緩存包含有效的數(shù)據(jù), 它會永遠(yuǎn)保持緩存副本,即使內(nèi)容中的內(nèi)部緩存已經(jīng)過期。
5.緩存的使用:頁面緩存
頁面緩存
頁面緩存指的是緩存整個頁面的內(nèi)容。頁面緩存可以發(fā)生在不同的地方。 例如,通過選擇適當(dāng)?shù)捻撁骖^,客戶端的瀏覽器可能會緩存網(wǎng)頁瀏覽有限時間。 Web應(yīng)用程序本身也可以在緩存中存儲網(wǎng)頁內(nèi)容。 在本節(jié)中,我們側(cè)重于后一種辦法。
頁面緩存可以被看作是 片段緩存一個特殊情況 。 由于網(wǎng)頁內(nèi)容是往往通過應(yīng)用布局來生成,如果我們只是簡單的在布局中調(diào)用beginCache() 和endCache(),將無法正常工作。 這是因為布局在CController::render()方法里的加載是在頁面內(nèi)容產(chǎn)生之后。
如果想要緩存整個頁面,我們應(yīng)該跳過產(chǎn)生網(wǎng)頁內(nèi)容的動作執(zhí)行。我們可以使用COutputCache作為動作 過濾器來完成這一任務(wù)。下面的代碼演示如何配置緩存過濾器:
public function filters() { return array( array( 'COutputCache', 'duration'=>100, 'varyByParam'=>array('id'), ), ); }
上述過濾器配置會使過濾器適用于控制器中的所有行動。 我們可能會限制它在一個或幾個行動通過使用插件操作器。 更多的細(xì)節(jié)中可以看過濾器。
Tip: 我們可以使用COutputCache作為一個過濾器,因為它從CFilterWidget繼承過來, 這意味著它是一個工具(widget)和一個過濾器。事實上,widget的工作方式和過濾器非常相似: 工具widget (過濾器filter)是在action動作里的內(nèi)容執(zhí)行前執(zhí)行,在執(zhí)行后結(jié)束。
6.緩存的使用:動態(tài)內(nèi)容
動態(tài)內(nèi)容(Dynamic Content)
當(dāng)使用fragment caching或page caching,我們常常遇到的這樣的情況 整個部分的輸出除了個別地方都是靜態(tài)的。例如,幫助頁可能會顯示靜態(tài)的幫助 信息,而用戶名稱顯示的是當(dāng)前用戶的。
解決這個問題,我們可以根據(jù)用戶名匹配緩存內(nèi)容,但是這將是我們寶貴空間一個巨大的浪費(fèi),因為緩存除了用戶名其他大部分內(nèi)容是相同的。我們還可以把網(wǎng)頁切成幾個片段并分別緩存,但這種情況會使頁面和代碼變得非常復(fù)雜。更好的方法是使用由[ CController ]提供的動態(tài)內(nèi)容dynamic content功能 。
動態(tài)內(nèi)容是指片段輸出即使是在片段緩存包括的內(nèi)容中也不會被緩存。即使是包括的內(nèi)容是從緩存中取出,為了使動態(tài)內(nèi)容在所有時間是動態(tài)的,每次都得重新生成。出于這個原因,我們要求 動態(tài)內(nèi)容通過一些方法或函數(shù)生成。
調(diào)用CController::renderDynamic()在你想的地方插入動態(tài)內(nèi)容。
...別的HTML內(nèi)容... <?php if($this->beginCache($id)) { ?> ...被緩存的片段內(nèi)容... <?php $this->renderDynamic($callback); ?> ...被緩存的片段內(nèi)容... <?php $this->endCache(); } ?> ...別的HTML內(nèi)容...
在上面的, $callback指的是有效的PHP回調(diào)。它可以是指向當(dāng)前控制器類的方法或者全局函數(shù)的字符串名。它也可以是一個數(shù)組名指向一個類的方法。其他任何的參數(shù),將傳遞到renderDynamic()方法中。回調(diào)將返回動態(tài)內(nèi)容而不是僅僅顯示它。
希望本文所述對大家基于Yii框架的PHP程序設(shè)計有所幫助。
更多YII Framework框架教程之緩存用法詳解相關(guān)文章請關(guān)注PHP中文網(wǎng)!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)
