Doctrine_Cacheは直感的で使いやすいキャッシュのソリューションを提供します。:
すべてのキャッシュドライバは次のようにインスタンス化されます:
// bootstrap.php
// ...
$options = array();
$cacheDriver = new Doctrine_Cache_Memcache($options);
それぞれのドライバは配列$options用の独自の値を持ちます。
Memcacheドライバはキャッシュレコードをmemcachedサーバーに保存します。Memcachedはハイパフォーマンスで、 分散型のメモリオブジェクトキャッシュシステムです。これをバックエンドに使うには、memcachedデーモンとPECLのmemcacheエクステンションが必要です。
Memcacheキャッシュドライバは次のコードでインスタンス化できます:
// bootstrap.php
// ...
$servers = array(
'host' => 'localhost',
'port' => 11211,
'persistent' => true
);
$cacheDriver = new Doctrine_Cache_Memcache(array(
'servers' => $servers,
'compression' => false
)
);
Memcacheは複数のサーバーを許可します。
Memcacheドライバで利用できるオプション:
| オプション | データ型 | デフォルト値 | 説明 |
|---|---|---|---|
| servers | array | array(array('host' => 'localhost','port' => 11211, 'persistent' => true)) | memcachedサーバーの配列; それぞれのmemcachedサーバーは連想配列で記述される: 'host' => (string) : memcachedサーバーの名前、'port' => (int) : memcachedサーバーのポート、'persistent' => (bool) : memcachedサーバーへの永続接続を使うかどうか |
| compression | boolean | false | 即座に圧縮したい場合はtrue |
Alternative PHP Cache (APC)はフリーでPHPのためのオープンなオプコードキャッシュです。これはPHPの中間コードのキャッシュと最適化のための頑強なフレームワークとも認識されています。DoctrineのAPCキャッシュドライバはキャッシュレコードを共用メモリに保存します。
次のコードでAPCキャッシュドライバをインスタンス化できます:
// bootstrap.php
// ...
$cacheDriver = new Doctrine_Cache_Apc();
Dbキャッシュバックエンドはキャッシュレコードを任意のデータベースに保存します。通常は処理が速いフラットファイルベースのデータベースが使われます(sqliteなど)。
次のコードでデータベースキャッシュをインスタンス化できます:
// bootstrap.php
// ...
$cacheConn = Doctrine_Manager::connection(new PDO('sqlite::memory:'));
$cacheDriver = new Doctrine_Cache_Db(array('connection' => $cacheConn));
DoctrineはDQLクエリの最終結果(データ)と同様にDQLの解析処理の結果をキャッシュする方法を提供します。これら2つのキャッシュメカニズムはパフォーマンスを大いに向上させます。DQLクエリ実行の標準ワークフローを考えてみましょう:
これらのフェーズはとても時間がかかります。とりわけクエリをデータベースサーバーに送信するフェーズ4は時間がかかります。Doctrineクエリキャッシュが実行されているとき次のフェーズが行われます:
DQLクエリが有効なキャッシュエントリーを持つ場合キャッシュされたSQLクエリが使われ、さもなければフェーズ2-3が実行されこれらのステップの結果がキャッシュに保存されます。最新のクエリ結果を常に得られるのでクエリキャッシュには不都合なことはありません。
本番環境では常にクエリキャッシュを使うべきです。すなわち開発期間も簡単に使えます。DQLクエリを変更して実行するときキャッシュが修正されたことをDoctrineが最初に確認して新しいキャッシュエントリを作ります。そのためキャッシュを取り消す必要はありません。
クエリキャッシュの効率性がプリペアードステートメントの使い方(ともかくDoctrineはデフォルトで使用)に依存するのは無意味です。動的なクエリの部分を直接埋め込む代わりに常にプレースホルダーを使うべきです。
結果キャッシュを使えば状況がよくなります。クエリ処理は次のようになります(有効なキャッシュエントリが見つかることが前提):
ご覧の通り、結果キャッシュは以前示されたクエリキャッシュを暗に伝えます。クエリによって返されるデータが最新である必要がなければ結果キャッシュを使うことを常に考えるべきです。
Doctrine_Core::ATTR_QUERY_CACHE属性を使用することで接続もしくは管理レベルのクエリキャッシュドライバを設定できます。接続レベルのキャッシュドライバを設定することはこの接続で実行されるすべてのドライバは特定のキャッシュドライバを使用するのに大してマネージャーレベルのキャッシュドライバを設定することは(接続レベルでオーバーライドされない限り)すべての接続が任意のキャッシュドライバを使用することを意味します。
マネージャーレベルのクエリキャッシュドライバを設定する:
// bootstrap.php
// ...
$manager->setAttribute(Doctrine_Core::ATTR_QUERY_CACHE, $cacheDriver);
$cacheDriverの値はこの章の前のセクションでインスタンス化されたドライバになります。
接続レベルのキャッシュドライバを設定する:
// bootstrap.php
// ...
$conn->setAttribute(Doctrine_Core::ATTR_QUERY_CACHE, $cacheDriver);
以前の章でグローバルキャッシュの属性を使いました。これらの属性はクエリレベルでオーバーライドできます。useQueryCache()を呼び出すことでキャッシュドライバをオーバーライドしてこれにDoctrineの有効なキャッシュドライバを渡すことができます。これはクエリキャッシュにはほとんど意味ありませんが可能です:
$q = Doctrine_Query::create()
->useQueryCache(new Doctrine_Cache_Apc());
Doctrine_Core::ATTR_RESULT_CACHEを使用することで接続もしくはマネージャーレベルの結果キャッシュドライバを設定できます。接続レベルのキャッシュドライバはこの接続で実行されるすべてのクエリが指定されたキャッシュドライバを使用するのに対してマネージャーレベルのキャッシュドライバは(接続レベルでオーバーライドされない限り)すべての接続が任意のキャッシュドライバを使用することを意味します。
マネージャーレベルのキャッシュドライバを設定する:
// bootstrap.php
// ...
$manager->setAttribute(Doctrine_Core::ATTR_RESULT_CACHE, $cacheDriver);
接続レベルのキャッシュドライバを設定する:
// bootstrap.php
// ...
$conn->setAttribute(Doctrine_Core::ATTR_RESULT_CACHE, $cacheDriver);
通常キャッシュエントリは同じ時間に対してのみ有効です。Doctrine_Core::ATTR_RESULT_CACHE_LIFESPANを使用することでキャッシュエントリの有効な期間のためのグローバルな値を設定できます。
寿命を1時間に設定する(60秒 * 60 = 1時間 = 3600秒):
// bootstrap.php
// ...
$manager->setAttribute(Doctrine_Core::ATTR_RESULT_CACHE_LIFESPAN, 3600);
キャッシュドライバを設定したのでuserResultCache()メソッドを呼び出すことでDQLクエリを使うことができます:
blog投稿のタイトルとコメントの数を取得する:
$q = Doctrine_Query::create();
->select('b.title, COUNT(c.id) count')
->from('BlogPost b')
->leftJoin('b.Comments c')
->limit(10)
->useResultCache(true);
$blogPosts = $q->execute();
以前の章でグローバルキャッシュ属性を使いました。これらの属性はクエリレベルでオーバーライドできます。useCache()を呼び出してキャッシュドライバをオーバーライドしこれらにDoctrineのキャッシュドライバのインスタンスを渡すことができます。
$q = Doctrine_Query::create()
->useResultCache(new Doctrine_Cache_Apc());
setResultCacheLifeSpan()を呼び出すことでもlifespan属性をオーバーライドできます:
$q = Doctrine_Query::create()
->setResultCacheLifeSpan(60 * 30);
開発と本番環境の両方でDoctrineのキャッシュ機能を使うことは大いにお勧めします。使うことで不都合な影響はなくアプリケーションのパフォーマンスの改善に役立ちます。
キャッシュ機能はこの本で検討される最後から2番目の機能です。この後のDoctrineで使われているテクノロジー、コーディング規約とユニットテストの章はまとめです。最後の機能であるMigrationsを検討するために移動しましょう。