深入解析PHP的Yii架構中的緩衝功能,yii架構
資料緩衝是指將一些 PHP 變數儲存到緩衝中,使用時再從緩衝中取回。它也是更進階緩衝特性的基礎,例如查詢快取和內容緩衝。
如下代碼是一個典型的資料緩衝使用模式。其中 $cache 指向緩衝組件:
// 嘗試從緩衝中取回 $data $data = $cache->get($key);if ($data === false) { // $data 在緩衝中沒有找到,則重新計算它的值 // 將 $data 存放到緩衝供下次使用 $cache->set($key, $data);}// 這兒 $data 可以使用了。
緩衝組件
資料緩衝需要緩衝組件提供支援,它代表各種緩衝儲存空間,例如記憶體,檔案,資料庫。
緩衝組件通常註冊為應用程式組件,這樣它們就可以在全域進行配置與訪問。如下代碼示範了如何配置應用程式組件 cache 使用兩個 memcached 伺服器:
'components' => [ 'cache' => [ 'class' => 'yii\caching\MemCache', 'servers' => [ [ 'host' => 'server1', 'port' => 11211, 'weight' => 100, ], [ 'host' => 'server2', 'port' => 11211, 'weight' => 50, ], ], ],],
然後就可以通過 Yii::$app->cache 訪問上面的緩衝組件了。
由於所有緩衝組件都支援同樣的一系列 API ,並不需要修改使用緩衝的業務代碼就能直接替換為其他底層緩衝組件,只需在應用配置中重新設定一下就可以。例如,你可以將上述配置修改為使用 yii\caching\ApcCache:
'components' => [ 'cache' => [ 'class' => 'yii\caching\ApcCache', ],],
Tip: 你可以註冊多個緩衝組件,很多依賴緩衝的類預設調用名為 cache 的組件(例如 yii\web\UrlManager)。
支援的緩衝儲存空間
Yii 支援一系列緩衝儲存空間,概況如下:
- yii\caching\ApcCache:使用 PHP APC 擴充。這個選項可以認為是集中式應用程式環境中(例如:單一伺服器,沒有獨立的負載平衡器等)最快的緩衝方案。
- yii\caching\DbCache:使用一個資料庫的表格儲存體快取資料。要使用這個緩衝,你必須建立一個與 yii\caching\DbCache::cacheTable 對應的表。
- yii\caching\DummyCache: 僅作為一個緩衝預留位置,不實現任何真正的緩衝功能。這個組件的目的是為了簡化那些需要查詢快取有效性的代碼。例如,在開發中如果伺服器沒有實際的緩衝支援,用它配置一個緩衝組件。一個真正的快取服務啟用後,可以再切換為使用相應的緩衝組件。兩種條件下你都可以使用同樣的代碼 Yii::$app->cache->get($key) 嘗試從緩衝中取回資料而不用擔心 Yii::$app->cache 可能是 null。
- yii\caching\FileCache:使用標準檔案儲存體快取資料。這個特別適用於緩衝大塊資料,例如一個整頁的內容。
- yii\caching\MemCache:使用 PHP memcache 和 memcached 擴充。這個選項被看作分布式應用環境中(例如:多台伺服器,有負載平衡等)最快的緩衝方案。
- yii\redis\Cache:實現了一個基於 Redis 索引值對儲存空間的緩衝組件(需要 redis 2.6.12 及以上版本的支援 )。
- yii\caching\WinCache:使用 PHP WinCache(另可參考)擴充.
- yii\caching\XCache:使用 PHP XCache擴充。
- yii\caching\ZendDataCache:使用 Zend Data Cache 作為底層緩衝媒介。
- Tip: 你可以在同一個應用程式中使用不同的緩衝儲存空間。一個常見的策略是使用基於記憶體的緩衝儲存空間儲存小而常用的資料(例如:統計資料),使用基於檔案或資料庫的緩衝儲存空間儲存大而不太常用的資料(例如:網頁內容)。
緩衝 API
所有緩衝組件都有同樣的基類 yii\caching\Cache ,因此都支援如下 API:
- yii\caching\Cache::get():通過一個指定的鍵(key)從緩衝中取回一項資料。如果該項資料不存在於緩衝中或者已經到期/失效,則傳回值 false。
- yii\caching\Cache::set():將一項資料指定一個鍵,存放到緩衝中。
- yii\caching\Cache::add():如果緩衝中未找到該鍵,則將指定資料存放到緩衝中。
- yii\caching\Cache::mget():通過指定的多個鍵從緩衝中取回多項資料。
- yii\caching\Cache::mset():將多項資料存放區到緩衝中,每項資料對應一個鍵。
- yii\caching\Cache::madd():將多項資料存放區到緩衝中,每項資料對應一個鍵。如果某個鍵已經存在於緩衝中,則該項資料會被跳過。
- yii\caching\Cache::exists():返回一個值,指明某個鍵是否存在於緩衝中。
- yii\caching\Cache::delete():通過一個鍵,刪除緩衝中對應的值。
- yii\caching\Cache::flush():刪除緩衝中的所有資料。
- 有些緩衝儲存空間如 MemCache,APC 支援以批量模式取回緩衝值,這樣可以節省取回快取資料的開支。 yii\caching\Cache::mget() 和 yii\caching\Cache::madd() API提供對該特性的支援。如果底層緩衝儲存空間不支援該特性,Yii 也會類比實現。
由於 yii\caching\Cache 實現了 PHP ArrayAccess 介面,緩衝組件也可以像數組那樣使用,下面是幾個例子:
$cache['var1'] = $value1; // 等價於: $cache->set('var1', $value1);$value2 = $cache['var2']; // 等價於: $value2 = $cache->get('var2');
緩衝鍵
儲存在緩衝中的每項資料都通過鍵作唯一識別。當你在緩衝中儲存一項資料時,必須為它指定一個鍵,稍後從緩衝中取回資料時,也需要提供相應的鍵。
你可以使用一個字串或者任意值作為一個緩衝鍵。當鍵不是一個字串時,它將會自動被序列化為一個字串。
定義一個緩衝鍵常見的一個策略就是在一個數組中包含所有的決定性因素。例如,yii\db\Schema 使用如下鍵儲存一個資料表的結構資訊。
[ __CLASS__, // 結構類名 $this->db->dsn, // 資料來源名稱 $this->db->username, // 資料庫登入使用者名稱 $name, // 表名];
如你所見,該鍵包含了可唯一指定一個資料庫表所需的所有必要資訊。
當同一個緩衝儲存空間被用於多個不同的應用時,應該為每個應用指定一個唯一的緩衝鍵首碼以避免緩衝鍵衝突。可以通過配置 yii\caching\Cache::keyPrefix 屬性實現。例如,在應用配置中可以編寫如下代碼:
'components' => [ 'cache' => [ 'class' => 'yii\caching\ApcCache', 'keyPrefix' => 'myapp', // 唯一鍵首碼 ],],
為了確保互連性,此處只能使用字母和數字。
緩衝到期
預設情況下,緩衝中的資料會永久存留,除非它被某些緩衝策略強制移除(例如:緩衝空間已滿,最老的資料會被移除)。要改變此特性,你可以在調用 yii\caching\Cache::set() 儲存一項資料時提供一個到期時間參數。該參數代表這項資料在緩衝中可保持有效多少秒。當你調用 yii\caching\Cache::get() 取回資料時,如果它已經過了逾時時間,該方法將返回 false,表明在緩衝中找不到這項資料。例如:
// 將資料在緩衝中保留 45 秒$cache->set($key, $data, 45);sleep(50);$data = $cache->get($key);if ($data === false) { // $data 已到期,或者在緩衝中找不到}
緩衝依賴
除了逾時設定,快取資料還可能受到緩衝依賴的影響而失效。例如,yii\caching\FileDependency 代表對一個檔案修改時間的依賴。這個依賴條件發生變化也就意味著相應的檔案已經被修改。因此,緩衝中任何到期的檔案內容都應該被置為失效狀態,對 yii\caching\Cache::get() 的調用都應該返回 false。
緩衝依賴用 yii\caching\Dependency 的衍生類別所表示。當調用 yii\caching\Cache::set() 在緩衝中儲存一項資料時,可以同時傳遞一個關聯的緩衝依賴對象。例如:
// 建立一個對 example.txt 檔案修改時間的緩衝依賴$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);// 快取資料將在30秒後逾時// 如果 example.txt 被修改,它也可能被更早地置為失效狀態。$cache->set($key, $data, 30, $dependency);// 緩衝會檢查資料是否已逾時。// 它還會檢查關聯的依賴是否已變化。// 符合任何一個條件時都會返回 false。$data = $cache->get($key);
下面是可用的緩衝依賴的概況:
- yii\caching\ChainedDependency:如果依賴鏈上任何一個依賴產生變化,則依賴改變。
- yii\caching\DbDependency:如果指定 SQL 陳述式的查詢結果發生了變化,則依賴改變。
- yii\caching\ExpressionDependency:如果指定的 PHP 運算式執行結果發生變化,則依賴改變。
- yii\caching\FileDependency:如果檔案的最後修改時間發生變化,則依賴改變。
- yii\caching\GroupDependency:將一項快取資料標記到一個組名,你可以通過調用 yii\caching\GroupDependency::invalidate() 一次性將相同組名的緩衝全部置為失效狀態。
查詢快取
查詢快取是一個建立在資料緩衝之上的特殊緩衝特性。它用於快取資料庫查詢的結果。
查詢快取需要一個 yii\db\Connection 和一個有效 cache 應用組件。查詢快取的基本用法如下,假設 $db 是一個 yii\db\Connection 執行個體:
$duration = 60; // 緩衝查詢結果60秒$dependency = ...; // 可選的緩衝依賴$db->beginCache($duration, $dependency);// ...這兒執行資料庫查詢...$db->endCache();
如你所見,beginCache() 和 endCache() 中間的任何查詢結果都會被緩衝起來。如果緩衝中找到了同樣查詢的結果,則查詢會被跳過,直接從緩衝中提取結果。
查詢快取可以用於 ActiveRecord 和 DAO。
Info: 有些 DBMS (例如:MySQL)也支援資料庫伺服器端的查詢快取。你可以選擇使用任一查詢快取機制。上文所述的查詢快取的好處在於你可以指定更靈活的緩衝依賴因此可能更加高效。
配置
查詢快取有兩個通過 yii\db\Connection 設定的配置項:
yii\db\Connection::queryCacheDuration: 查詢結果在緩衝中的有效期間,以秒錶示。如果在調用 yii\db\Connection::beginCache() 時傳遞了一個顯式的時值參數,則配置中的有效期間時值會被覆蓋。
yii\db\Connection::queryCache: 緩衝應用組件的 ID。預設為 'cache'。只有在設定了一個有效緩衝應用組件時,查詢快取才會有效。
限制條件
當查詢結果中含有資源控制代碼時,查詢快取無法使用。例如,在有些 DBMS 中使用了 BLOB 列的時候,緩衝結果會為該資料列返回一個資源控制代碼。
有些緩衝儲存空間有大小限制。例如,memcache 限制每條資料最大為 1MB。因此,如果查詢結果的大小超出了該限制,則會導致緩衝失敗。
片段快取
片段快取指的是快取頁面面內容中的某個片段。例如,一個頁面顯示了逐年銷售額的摘要表格,可以把表格緩衝下來,以消除每次請求都要重建表格的耗時。片段快取是基於資料緩衝實現的。
在視圖中使用以下結構啟用片段快取:
if ($this->beginCache($id)) { // ... 在此產生內容 ... $this->endCache();}
調用 yii\base\View::beginCache() 和 yii\base\View::endCache() 方法包裹內容產生邏輯。如果緩衝中存在該內容,yii\base\View::beginCache() 方法將渲染內容並返回 false,因此將跳過內容產生邏輯。否則,內容產生邏輯被執行,一直執行到 yii\base\View::endCache() 時,產生的內容將被捕獲並儲存在緩衝中。
和[資料緩衝]一樣,每個片段快取也需要全域唯一的 $id 標記。
緩衝選項
如果要為片段快取指定額外配置項,請通過向 yii\base\View::beginCache() 方法第二個參數傳遞配置數組。在架構內部,該數組將被用來配置一個 yii\widget\FragmentCache 小組件用以實現片段快取功能。
到期時間(duration)
或許片段快取中最常用的一個配置選項就是 yii\widgets\FragmentCache::duration 了。它指定了內容被緩衝的秒數。以下代碼緩衝內容最多一小時:
if ($this->beginCache($id, ['duration' => 3600])) { // ... 在此產生內容 ... $this->endCache();}
如果該選項未設定,則預設為 0,永不到期。
依賴
和[資料緩衝]一樣,片段快取的內容一樣可以設定緩衝依賴。例如一段被緩衝的文章,是否重新緩衝取決於它是否被修改過。
通過設定 yii\widgets\FragmentCache::dependency 選項來指定依賴,該選項的值可以是一個 yii\caching\Dependency 類的衍生類別,也可以是建立緩衝對象的配置數組。以下代碼指定了一個片段快取,它依賴於 update_at 欄位是否被更改過的。
$dependency = [ 'class' => 'yii\caching\DbDependency', 'sql' => 'SELECT MAX(updated_at) FROM post',];if ($this->beginCache($id, ['dependency' => $dependency])) { // ... 在此產生內容 ... $this->endCache();}
變化
緩衝的內容可能需要根據一些參數的更改而變化。例如一個 Web 應用程式支援多語言,同一段視圖代碼也許需要產生多個語言的內容。因此可以設定緩衝根據應用當前語言而變化。
通過設定 yii\widgets\FragmentCache::variations 選項來指定變化,該選項的值應該是一個標量,每個標量代表不同的變化係數。例如設定緩衝根據當前語言而變化可以用以下代碼:
if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) { // ... 在此產生內容 ... $this->endCache();}
開關
有時你可能只想在特定條件下開啟片段快取。例如,一個顯示表單的頁面,可能只需要在初次請求時緩衝表單(通過 GET 請求)。隨後請求所顯示(通過 POST 請求)的表單不該使用緩衝,因為此時表單中可能包含使用者輸入內容。鑒於此種情況,可以使用 yii\widgets\FragmentCache::enabled 選項來指定緩衝開關,如下所示:
if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) { // ... 在此產生內容 ... $this->endCache();}
緩衝嵌套
片段快取可以被嵌套使用。一個片段快取可以被另一個包裹。例如,評論被緩衝在裡層,同時整個評論的片段又被緩衝在外層的文章中。以下代碼展示了片段快取的嵌套使用:
if ($this->beginCache($id1)) { // ...在此產生內容... if ($this->beginCache($id2, $options2)) { // ...在此產生內容... $this->endCache(); } // ...在此產生內容... $this->endCache();}
可以為嵌套的緩衝設定不同的配置項。例如,內層緩衝和外層緩衝使用不同的到期時間。甚至當外層緩衝的資料到期失效了,內層緩衝仍然可能提供有效片段快取資料。但是,反之則不然。如果外層片段快取沒有到期而被視為有效,此時即使內層片段快取已經失效,它也將繼續提供同樣的快取複本。因此,你必須謹慎處理緩衝嵌套中的到期時間和依賴,否則外層的片段很有可能返回的是不符合你預期的失效資料。
譯註:外層的失效時間應該短於內層,外層的依賴條件應該低於內層,以確保最小的片段,返回的是最新的資料。
動態內容
使用片段快取時,可能會遇到一大段較為靜態內容中有少許動態內容的情況。例如,一個顯示著功能表列和目前使用者名的頁面頭部。還有一種可能是緩衝的內容可能包含每次請求都需要執行的 PHP 代碼(例如註冊資源套件的代碼)。這兩個問題都可以使用動態內容功能解決。
動態內容的意思是這部分輸出的內容不該被緩衝,即便是它被包裹在片段快取中。為了使內容保持動態,每次請求都執行 PHP 代碼產生,即使這些代碼已經被緩衝了。
可以在片段快取中調用 yii\base\View::renderDynamic() 去插入動態內容,如下所示:
if ($this->beginCache($id1)) { // ...在此產生內容... echo $this->renderDynamic('return Yii::$app->user->identity->name;'); // ...在此產生內容... $this->endCache();}
yii\base\View::renderDynamic() 方法接受一段 PHP 代碼作為參數。代碼的傳回值被看作是動態內容。這段代碼將在每次請求時都執行,無論其外層的片段快取是否被儲存。
您可能感興趣的文章:
- 詳解PHP的Yii架構中內建的前端資源套件的使用
- 簡介PHP的Yii架構中緩衝的一些進階用法
- PHP的Yii架構中View視圖的使用進階
- PHP的Yii架構中建立視圖和渲染視圖的方法詳解
- PHP的Yii架構中Model模型的學習教程
- 詳解PHP的Yii架構中的Controller控制器
- PHP的Yii架構中移除組件所綁定的行為的方法
- PHP的Yii架構中行為的定義與Binder 方法講解
- 深入講解PHP的Yii架構中的屬性(Property)
- 詳解PHP的Yii架構中擴充的安裝與使用
http://www.bkjia.com/PHPjc/1117069.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1117069.htmlTechArticle深入解析PHP的Yii架構中的緩衝功能,yii架構 資料緩衝是指將一些 PHP 變數儲存到緩衝中,使用時再從緩衝中取回。它也是更進階緩衝特性的...