頁面快取 ============ 頁面快取指的是快取整個頁面的內容。頁面快取可以發生在不同的地方。例如,通過選擇適當的頁面頭,客戶端的瀏覽器可能會快取網頁瀏覽有限時間。 Web 應用程式程式本身也可以在快取中儲存網頁內容。 頁面快取可以被看作是 [片段快取](/doc/guide/caching.fragment) 一個特殊情況 。 由於網頁內容是往往通過應用程式佈局來產生,如果我們只是簡單的在佈局中調用 [beginCache()|CBaseController::beginCache] 和 [endCache()|CBaseController::endCache],將無法正常工作。 這是因為佈局在 [CController::render()] 方法裡的加載是在頁面內容產生之後。 如果想要快取整個頁面,我們應該跳過產生網頁內容的動作執行。我們可以使用 [COutputCache] 作為動作 [篩選器](/doc/guide/basics.controller#filter)來完成這一任務。下面的程式碼展示如何配置快取篩選器: ~~~ [php] public function filters() { return array( array( 'COutputCache', 'duration'=>100, 'varyByParam'=>array('id'), ), ); } ~~~ 上述篩選器配置會使篩選器適用於控制器中的所有行動。 我們可能會限制它在一個或幾個行動透過使用插件操作器。 更多的細節可以看[篩選器](/doc/guide/basics.controller#filter)。 > Tip: 我們可以使用 [COutputCache] 作為一個篩選器,因為它從 [CFilterWidget] 繼承過來, 這意味著它是一個工具(widget)和一個篩選器。事實上,小工具的工作方式和篩選器非常相似: 小工具 (篩選器) 是在動作裡的內容執行前執行,在執行後結束。 HTTP 快取 ------------ 除了簡單快取動作的輸出,Yii 在版本 1.1.11 介紹了 [CHttpCacheFilter]。這個篩選器協助了前面所提到的,使用標頭來提示客戶端頁面的內容,自上一次請求後就沒有改變,所以伺服器不需要重新傳送內容。[CHttpCacheFilter] 可以像 [COutputCache] 一樣設置: ~~~ [php] public function filters() { return array( array( 'CHttpCacheFilter + index', 'lastModified'=>Yii::app()->db->createCommand("SELECT MAX(`update_time`) FROM {{post}}")->queryScalar(), ), ); } ~~~ 上述的程式碼會設定 `Last-Modified` 標頭成上一次文章被更新的日期。你也可以使用 [CHttpCacheFilter::lastModifiedExpression] 藉由 PHP 表達式來設定 `Last-Modified` 標頭。 > Tip|提示: [CHttpCacheFilter::lastModifiedExpression] 和 [CHttpCacheFilter::lastModified] 都可以使用 Unix 時間戳記或是人類可讀的字串來表示。後者可以被 [strtotime()](http://php.net/manual/function.strtotime.php) 解析,不需要額外的轉換。 這個 "Entity Tag"(或 `ETag`)標頭可以分別藉由像是 [CHttpCacheFilter::etagSeed] 和 [CHttpCacheFilter::etagSeedExpression] 的方法來設定。兩個都會被序列化(所以可以使用單一值或是一整個陣列),並且被用來產生一個被標記的、base64-encoded SHA1 編碼的內容來給 `ETag` 標投當作內容。這跟 [Apache Webserver](http://httpd.apache.org) 的方法不同,各家的伺服器也產生自己的 ETags。然而,非常符合 RFC,而且也成為一個框架中的主流的用法。 > Note|注意: 為了遵守 [RFC 2616,第 13.3.4 章節](http://tools.ietf.org/html/rfc2616#section-13.3.4), [CHttpCacheFilter] 會送出 `ETag` *和* `Last-Modified` 標頭,如果他們可以同時被產生。所以,兩者都會被客戶端用來做快取驗證。 當時體標籤被編碼,他們允許比 `Last-Modified` 標頭更複雜且/或更精確的快取策略。例如,一個 ETag 可能是無效的,當網站切換成另外一個主題。 > Tip|提示: 昂貴的表達式給 [CHttpCacheFilter::etagSeedExpression] 可以會違背 [CHttpCacheFilter] 的目的和產生不需要的負擔,因為每次的請求都要重新被評估。試著找出一個簡單的表達式,可以檢驗快取是否頁面的 *內容* 已經被修改了。 ### 搜尋引擎優化的影響 搜尋引擎機器很看重快取標頭。當一些網路爬蟲有限制每個網域下,在某一個時間區間有多少頁面可以被處理,使用快取標投可以幫助索引你的網站,因為可以減少需要處理的頁面數量。
$Id$