フラグメントキャッシュ
================

フラグメントキャッシュはページの断片をキャッシュする事を指します。
たとえば、ページ中に年間売り上げサマリの表がある場合、リクエスト毎にこれを生成する時間をなくすために、この表をキャッシュに保持できます。

フラグメントキャッシュを利用するには、[CController::beginCache()|CBaseController::beginCache()] と [CController::endCache()|CBaseController::endCache()] をコントローラのビュースクリプトで呼び出します。
二つのメソッドはキャッシュされるべきページ内容の始めと終わりをそれぞれマークします。
[データキャッシュ](/doc/guide/caching.data) と同じように、キャッシュされる断片を識別するために、ID が必要です。

~~~
[php]
...他の HTML コンテンツ...
<?php if($this->beginCache($id)) { ?>
...キャッシュされるコンテンツ...
<?php $this->endCache(); } ?>
...他の HTML コンテンツ...
~~~

上記中で、[beginCache()|CBaseController::beginCache()] が false を返したら、キャッシュ内容がその場所に自動的に挿入されます。
そうでなければ、上記中の `if` 文が実行され、[endCache()|CBaseController::endCache()] が呼び出されるまでの内容がキャッシュされます。

キャッシングオプション
---------------

[beginCache()|CBaseController::beginCache()] を呼び出す際、フラグメントキャッシュをカスタマイズするためのキャッシングオプションから成る配列を 2 番目のパラメータとして指定することが可能です。
実は、[beginCache()|CBaseController::beginCache()] と [endCache()|CBaseController::endCache()] メソッドは [COutputCache] ウィジェットの便宜的なラッパーです。
したがって、キャッシングオプションを [COutputCache] の任意のプロパティの初期値とすることが可能です。

### 持続時間

おそらく、もっとも一般的なオプションは、どれくらいの時間キャッシュが有効であるかを指定する [duration|COutputCache::duration] です。
これは、[CCache::set()] の有効期限パラメータに似ています。
下記のコードは最大 1 時間、コンテンツの断片をキャッシュします。

~~~
[php]
...他の HTML コンテンツ...
<?php if($this->beginCache($id, array('duration'=>3600))) { ?>
...キャッシュされるコンテンツ...
<?php $this->endCache(); } ?>
...他の HTML コンテンツ...
~~~

duration オプションを設定しない場合、この値はデフォルト値 60 が用いられ、60 秒後にキャッシュされたコンテンツが無効にされます。

バージョン 1.1.8 以降では、持続期間を 0 に設定すると、既存のキャッシュされたコンテンツがすべてキャッシュから削除されます。
持続期間が負の値である場合は、キャッシュは無効化されますが、既存のキャッシュされたコンテンツはキャッシュの中に残り続けます。
バージョン 1.1.8 より前は、持続期間が 0 または負の場合は、キャッシュが無効化されます。

### 依存関係

[データキャッシュ](/doc/guide/caching.data) のように、フラグメントキャッシュも、キャッシュ依存関係を持つことが出来ます。
たとえば、表示されている記事内容は記事内容が修正されたかどうかに依存します。

依存関係を指定するためには、[dependency|COutputCache::dependency] オプション ([ICacheDependency] を実装するオブジェクトか、あるいは、依存関係オブジェクトを生成するために使用できる設定の配列) を設定します。
下記コードは、断片のコンテンツがデータベースの `lastModified` カラム値の変更に依存することを指定しています。

~~~
[php]
...他の HTML コンテンツ...
<?php if($this->beginCache($id, array('dependency'=>array(
		'class'=>'system.caching.dependencies.CDbCacheDependency',
		'sql'=>'SELECT MAX(lastModified) FROM Post')))) { ?>
...キャッシュされるコンテンツ...
<?php $this->endCache(); } ?>
...他の HTML コンテンツ...
~~~

### バリエーション

キャッシュされるコンテンツは、いくつかのパラメータにより変化する場合があります。
たとえば、個人のプロフィールは、異なるユーザには異なって見えるかも知れません。
プロフィールの内容をキャッシュする場合は、キャッシュされたコピーをユーザ ID によって変化させたいと思うでしょう。
これは、本質的には、[beginCache()|CBaseController::beginCache()] を呼ぶ際に異なる ID を使うべきだ、ということです。

一定のスキームに従って ID を変化させるように開発者に要求する代わりに、[COutputCache] にはそのような機能がすでに組み込まれています。
下記は概要です:

   - [varyByRoute|COutputCache::varyByRoute]: このオプションを true に設定することで、キャッシュされるコンテンツは [ルート (経路)](/doc/guide/basics.controller#sec-2) によって変化するようになります。
したがって、要求されるコントローラとアクションのすべての組み合わせに対して、それぞれ独立して、キャッシュされるコンテンツが存在しうることになります。

   - [varyBySession|COutputCache::varyBySession]: このオプションを true に設定することで、セッション ID によって変化するキャッシュされるコンテンツを作る事ができます。
したがって、それぞれのユーザセッションでは、異なるコンテンツが表示され、それらが全てキャッシュから読み出されます。

   - [varyByParam|COutputCache::varyByParam]: このオプションに名前の配列を設定することで、指定された GET パラメータの値によって変化するキャッシュされるコンテンツを作る事ができます。
たとえば、ページで `id` GET パラメータにより記事内容を表示する場合、`array('id')` を [varyByParam|COutputCache::varyByParam] に指定する事で、すべての記事内容をキャッシュする事ができます。
このような変化がない場合は、単一の記事内容しかキャッシュすることが出来ないでしょう。

   - [varyByExpression|COutputCache::varyByExpression]: このオプションに PHP の式を設定することで、この PHP の式の結果に従って変化するキャッシュされるコンテンツを作る事ができます。

### リクエストタイプ

特定のリクエストタイプに対してのみ、フラグメントキャッシュを有効にしたい場合があります。
たとえば、フォームを表示するページでは、最初の (GET リクエストによる) リクエストの場合だけはキャッシュしたいと思いますが、その後の (POST リクエストによる) フォームの表示では、フォームにユーザ入力が含まれている可能性があるため、キャッシュをすべきではありません。
そのような場合に、[requestTypes|COutputCache::requestTypes] オプションを指定することができます:

~~~
[php]
...他の HTML コンテンツ...
<?php if($this->beginCache($id, array('requestTypes'=>array('GET')))) { ?>
...キャッシュされるコンテンツ...
<?php $this->endCache(); } ?>
...他の HTML コンテンツ...
~~~

キャッシュのネスト
--------------

フラグメントキャッシュはネストすることができます。
すなわち、キャッシュされる断片を、より大きなキャッシュされる断片で囲むことが出来ます。
たとえば、コメントが内側のフラグメントキャッシュ内にキャッシュされ、それらが外側のフラグメントキャッシュにに記事内容と一緒にキャッシュされます。

~~~
[php]
...他の HTML コンテンツ...
<?php if($this->beginCache($id1)) { ?>
...外側のキャッシュされるコンテンツ...
	<?php if($this->beginCache($id2)) { ?>
	...内側のキャッシュされるコンテンツ...
	<?php $this->endCache(); } ?>
...外側のキャッシュされるコンテンツ...
<?php $this->endCache(); } ?>
...他の HTML コンテンツ...
~~~

ネストされたキャッシュには、異なるキャッシュオプションを設定することができます。
たとえば、上記の例における内側のキャッシュと外側のキャッシュに対して、異なる持続期間の値を設定する事が可能です。
これによって、外側のキャッシュでキャッシュされたデータが無効にされる場合でも、内側のキャッシュが有効な内側の断片を提供することが可能になります。
しかし、その逆は真ではありません。
外側のキャッシュが有効であると判断された場合には、内側のキャッシュが無効になった後でも、外側のキャッシュが古くなったコンテンツのコピーを提供し続けます。
ネストされたキャッシュの持続時間や依存関係の設定を間違うと、無効になった内側のキャッシュデータが外側のキャッシュに残り続けることになるので、注意が必要です。

<div class="revision">$Id$</div>