PHP—yii架構緩衝知識集錦

來源:互聯網
上載者:User
Yii是一個高效能的PHP5的web應用程式開發架構。通過一個簡單的命令列工具 yiic 可以快速建立一個web應用程式的代碼架構,開發人員可以在產生的程式碼架構基礎上添加商務邏輯,以快速完成應用程式的開發。緩衝是用於提升網站效能的一種即簡單又有效途徑。稍微有點規模的網站都會通過儲存相對靜態資料至緩衝以備所需,這樣我們可以省去從資料庫查詢然後產生這些資料的時間,通過減輕資料庫的壓力從而提升網站的效能。Yii作為一個強大的php開源架構,再緩衝這塊,Yii對各種流行的緩衝都提供了介面,我們可以根據實際的需要使用不同的緩衝。

yii的緩衝相關組件存放在yii/framework/caching的目錄內,通過查看該目錄,我們可以知道yii所支援的都有哪些緩衝。下面我們對相關檔案做一些簡單的介紹:

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 中使用緩衝主要包括配置和訪問緩衝組件 。 下面以分別以使用 memcache 緩衝組件和檔案快取組件為例做二個說明:

(1)memcache 緩衝樣本:

如下的應用配置指定了一個使用兩台快取服務器的 memcache 緩衝組件:

array(......'components'=>array(......'phpernote_cache'=>array('class'=>'system.caching.CMemCache','servers'=>array(array('host'=>'10.201.1.101', 'port'=>11211, 'weight'=>60),array('host'=>'10.201.1.102', 'port'=>11211, 'weight'=>40),),),),);

程式啟動並執行時候可以再控制器方法中通過 Yii::app()->phpernote_cache 來訪問緩衝組件,例如:

Yii::app ()->phpernote_cache->set($key,$value,$expire);

Yii::app()->phpernote_cache->add($id,$value);

Yii::app ()->phpernote_cache->get($key);

(2)檔案快取樣本:

1. 在config檔案加入緩衝配置資訊

array(......'components'=>array(......'cache'=>array('class'=>'system.caching.CFileCache','directoryLevel'=>2),),),);

以上配置中 directoryLevel 設定的是快取檔案的目錄深度;如果快取頁面面特別多,這個值需要設定大點,否則每個目錄下的頁面會很多。

2. 在要做緩衝的控制器裡定義過濾器。

public function filters(){return array(array('COutputCache + post, list','duration'=>3600,'varyByParam'=>array('id','page'),'dependency'=>array('class'=>'CDbCacheDependency','sql'=>'SELECT MAX(id) FROM phpernote_article',));}

COutputCache 是用於處理緩衝的類,如果只填'COutputCache',則控制器裡所有action都會通過緩衝過濾,定義'COutputCache + post, list',表示只對以下方法進行緩衝:actionPost, actionList 。

duration 是緩衝的時間,單位是秒,

varyByParam 是指定一系列GET參數名稱列表, 使用相應的值去確定緩衝內容的版本,即同一個action用於區分是不同頁面的的參數,此處我以id和page來區分不同頁面。

除varyByParam以外,還可以採用其他的條件來區分頁面:

varyByExpression:指定緩衝內容通過自訂的PHP運算式的結果而變化

varyByRoute:指定緩衝內容基於請求的路由不同而變化 (controller 和 action)

varyBySession:指定是否緩衝內容. 因使用者session不同而變化

dependency'指定緩衝失效依賴關係:可指定檔案或資料庫;本樣本指定的是資料庫依賴 CDbCacheDependency ,通過資料表的某個值的變化來確定緩衝是否失效。例如,如果在表中新增了一條記錄,即使緩衝才過了5分鐘(<3600),仍然判斷為失效,從而查詢資料庫,產生整個頁面,再次緩衝;

提示:yii也可以支援Redis,需要裝一個外掛程式:http://www.yiibase.com/download/view/32.html

緩衝可以在不同的層級使用。在最低層級,可用來緩衝單個資料(資料緩衝)。往上一級,我們緩衝一個由視圖指令碼產生的頁面片斷(片段快取)。在最進階別,可儲存整個頁面以便需要的時候直接從緩衝讀取。本文說明頁面緩衝的配置及實現效果;

資料緩衝

資料緩衝即儲存一些 PHP 變數到緩衝中,以後再從緩衝中取出來。出於此目的,緩衝組件的基類 CCache 提供了兩個最常用的方法: set() 和 get()。

要在緩衝中儲存一個變數 $value ,我們選擇一個唯一 ID 並調用 set() 儲存它:

Yii::app()->cache->set($id, $value);緩衝的資料將一直留在緩衝中,除非它由於某些緩衝策略(例如緩衝空間已滿,舊的資料被刪除)而被清除。 要改變這種行為,我們可以在調用 set() 的同時提供一個到期參數,這樣在設定的時間段之後,快取資料將被清除:

// 值$value 在緩衝中最多保留30秒
Yii::app()->cache->set($id, $value, 30);稍後當我們需要訪問此變數時(在同一個或不同的 Web 請求中),就可以通過 ID 調用 get() 從緩衝中將其取回。 如果返回的是 false,表示此值在緩衝中不可用,我們應該重建它。

$value=Yii::app()->cache->get($id);if($value===false){    // 因為在緩衝中沒找到 $value ,重建它 ,    // 並將它存入緩衝以備以後使用:    // Yii::app()->cache->set($id,$value);}

為要存入緩衝的變數選擇 ID 時,要確保此 ID 對應用中所有其他存入緩衝的變數是唯一的。而在不同的應用之間,這個 ID 不需要是唯一的。緩衝組件具有足夠的智慧區分不同應用中的 ID。

一些緩衝儲存空間,例如 MemCache, APC, 支援以批量模式擷取多個緩衝值。這可以減少擷取快取資料時帶來的開銷。從版本 1.0.8 起,Yii 提供了一個新的名為 mget() 的方法。它可以利用此功能。如果底層緩衝儲存空間不支援此功能,mget() 依然可以類比實現它。

要從緩衝中清除一個緩衝值,調用 delete(); 要清楚緩衝中的所有資料,調用 flush()。 當調用 flush() 時一定要小心,因為它會同時清除其他應用中的緩衝。

提示: 由於 CCache 實現了 ArrayAccess,因此緩衝組件也可以像一個數組一樣使用。下面是幾個例子:

$cache=Yii::app()->cache;$cache['username']=$value1;  // 相當於: $cache->set('username',$value1);$value2=$cache['username'];  // 相當於: $value2=$cache->get('username');

1. 緩衝依賴

除了到期設定,快取資料也可能會因為依賴條件發生變化而失效。例如,如果我們緩衝了某些檔案的內容,而這些檔案發生了改變,我們就應該讓緩衝的資料失效,並從檔案中讀取最新內容而不是從緩衝中讀取。

我們將一個依賴關係表現為一個 CCacheDependency 或其子類的執行個體。 當調用 set() 時,我們連同要緩衝的資料將其一同傳入。如下面這段代碼的意思就是此值將在30秒後失效,但如果依賴的檔案發生了變化則立即失效:

Yii::app()->cache->set($id, $value, 30, new CFileCacheDependency('FileName'));

現在如果我們通過調用get() 從緩衝中擷取 $value ,依賴關係將被檢查,如果發生改變,我們將會得到一個 false 值,表示資料需要被重建。

如下是可用的緩衝依賴的簡要說明:

CFileCacheDependency: 如果檔案的最後修改時間發生改變,則依賴改變。

CDirectoryCacheDependency: 如果目錄和其子目錄中的檔案發生改變,則依賴改變。

CDbCacheDependency: 如果指定 SQL 陳述式的查詢結果發生改變,則依賴改變。

CGlobalStateCacheDependency: 如果指定的全域狀態發生改變,則依賴改變。全域狀態是應用中的一個跨請求,跨會話的變數。它是通過 CApplication::setGlobalState() 定義的。

CChainedCacheDependency: 如果鏈中的任何依賴發生改變,則此依賴改變。

CExpressionDependency: 如果指定的 PHP 運算式的結果發生改變,則依賴改變。此類從版本 1.0.4 起可用。

片段快取(Fragment Caching)

片段快取指緩衝網頁某片段。例如,如果一個頁面在表中顯示每年的銷售摘要,我們可以儲存此表在緩衝中,減少每次請求需要重新產生的時間。

要使用片段快取,在控制器視圖指令碼中調用 CController::beginCache() 和 CController::endCache() 。這兩種方法開始和結束包括的頁面內容將被緩衝。類似data caching ,我們需要一個編號,識別被緩衝的片段。例如下面這段代碼如果beginCache() 返回false,緩衝的內容將此地方自動插入; 否則,在if語句內的內容將被執行並在endCache()觸發時緩衝。

......<?php if($this->beginCache($id)) { ?>...被緩衝的內容...<?php $this->endCache(); } ?>......

1. 緩衝選項(Caching Options)

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

有效期間(Duration)

也許是最常見的選項是duration,指定了內容在緩衝中多久有效。和CCache::set()到期參數有點類似。下面的代碼緩衝內容片段最多一小時:

......<?php if($this->beginCache($id, array('duration'=>3600))) { ?>...被緩衝的內容...<?php $this->endCache(); } ?>......

如果我們不設定期限,它將預設為60 ,這意味著60秒後緩衝內容將無效。

依賴(Dependency)

像data caching ,內容片段被緩衝也可以有依賴。例如,文章的內容被顯示取決於文章是否被修改。

要指定一個依賴,我們建立了dependency選項,可以是一個實現[ICacheDependency]的對象或可用於產生依賴對象的配置數組。下面的代碼指定片段內容取決於lastModified 列的值是否變化:

<?php if($this->beginCache($id, array('dependency'=>array(        'class'=>'system.caching.dependencies.CDbCacheDependency',        'sql'=>'SELECT MAX(lastModified) FROM Post')))) { ?>...被緩衝的內容...<?php $this->endCache(); } ?

變化(Variation)

緩衝的內容可根據一些參數變化。例如,每個人的檔案都不一樣。緩衝的檔案內容將根據每個人ID變化。這意味著,當調用beginCache()時將用不同的ID。

COutputCache內建了這一特徵,程式員不需要編寫根據ID變動內容的模式。以下是摘要。

varyByRoute: 設定此選項為true ,緩衝的內容將根據route變化。因此,每個控制器和行動的組合將有一個單獨的緩衝內容。

varyBySession: 設定此選項為true ,緩衝的內容將根據session ID變化。因此,每個使用者會話可能會看到由緩衝提供的不同內容。

varyByParam: 設定此選項的數組裡的名字,緩衝的內容將根據GET參數的值變動。例如,如果一個頁面顯示文章的內容根據id的GET參數,我們可以指定varyByParam為array('id'),以使我們能夠緩衝每篇文章內容。如果沒有這樣的變化,我們只能能夠緩衝某一文章。

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

<?php if($this->beginCache($id, array('requestTypes'=>array('GET')))) { ?>...被緩衝的內容...<?php $this->endCache(); } ?>

2. 嵌套緩衝(Nested Caching)

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

<?php if($this->beginCache($id1)) { ?>...外部被緩衝內容...    <?php if($this->beginCache($id2)) { ?>    ...內部被緩衝內容...    <?php $this->endCache(); } ?>...外部被緩衝內容...<?php $this->endCache(); } ?>

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

頁面緩衝

頁面緩衝指的是緩衝整個頁面的內容。頁面緩衝可以發生在不同的地方。例如,通過選擇適當的頁面頭,用戶端的瀏覽器可能會緩衝網頁瀏覽有限時間。Web應用程式本身也可以在緩衝中儲存網頁內容。 在本節中,我們側重於後一種辦法。

頁面緩衝可以被看作是 片段快取一個特殊情況 。 由於網頁內容是往往通過應用布局來產生,如果我們只是簡單的在布局中調用beginCache() 和endCache(),將無法正常工作。這是因為布局在CController::render()方法裡的載入是在頁面內容產生之後。

如果想要緩衝整個頁面,我們應該跳過產生網頁內容的動作執行。我們可以使用COutputCache作為動作 過濾器來完成這一任務。下面的代碼示範如何配置緩衝過濾器:

public function filters(){    return array(        array(            'COutputCache',            'duration'=>100,            'varyByParam'=>array('id'),        ),    );}

上述過濾器配置會使過濾器適用於控制器中的所有行動。 我們可能會限制它在一個或幾個行動通過使用外掛程式操作器。 更多的細節中可以看過濾器。

提示: 我們可以使用COutputCache作為一個過濾器,因為它從CFilterWidget繼承過來, 這意味著它是一個工具(widget)和一個過濾器。事實上,widget的工作方式和過濾器非常相似。工具widget (過濾器filter)是在action動作裡的內容執行前執行,在執行後結束。

6.緩衝的使用:動態內容(Dynamic Content)

當使用fragment caching或page caching,我們常常遇到的這樣的情況 整個部分的輸出除了個別地方都是靜態。例如,協助頁可能會顯示靜態協助 資訊,而使用者名稱稱顯示的是目前使用者的。

解決這個問題,我們可以根據使用者名稱匹配緩衝內容,但是這將是我們寶貴空間一個巨大的浪費,因為緩衝除了使用者名稱其他大部分內容是相同的。我們還可以把網頁切成幾個片段並分別緩衝,但這種情況會使頁面和代碼變得非常複雜。更好的方法是使用由[ CController ]提供的動態內容dynamic content功能 。

動態內容是指片段輸出即使是在片段快取包括的內容中也不會被緩衝。即使是包括的內容是從緩衝中取出,為了使動態內容在所有時間是動態,每次都得重建。出於這個原因,我們要求 動態內容通過一些方法或函數產生。

調用CController::renderDynamic()在你想的地方插入動態內容。

<?php if($this->beginCache($id)) { ?>...被緩衝的片段內容...    <?php $this->renderDynamic($callback); ?>...被緩衝的片段內容...<?php $this->endCache(); } ?>

在上面的,$callback指的是有效PHP回調。它可以是指向當前控制器類的方法或者全域函數的字串名。也可以是一個數組名指向一個類的方法。其他任何的參數,將傳遞到 renderDynamic()方法中。回調將返回動態內容而不是僅僅顯示它。

關於Yii架構緩衝的知識這篇文章基本做了一個總結,希望大家在工作當中能用的到。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.