SymfonyとDoctrineの記事になります。
今回の記事の各Versionは下記です。
Symfony 3.4
Doctrine 2.12
EC-CUBEというECサイトフレームワークを使用している案件で、改めてキャッシュ周りを見直したので備忘録になります。
発端はDoctrine 1.xのときにキャッシュを削除する際に、前方一致で削除する、deleteByPrefix
がなくなっていたことです。
キャッシュ周りの変更をまとめると下記になります。(英文まま)
## Cache Changes - Renamed old AbstractCache to CacheProvider - Dropped the support to the following functions of all cache providers: - CacheProvider::deleteByWildcard - CacheProvider::deleteByRegEx - CacheProvider::deleteByPrefix - CacheProvider::deleteBySuffix - CacheProvider::deleteAll will not remove ALL entries, it will only mark them as invalid - CacheProvider::flushAll will remove ALL entries, namespaced or not - Added support to MemcachedCache - Added support to WincacheCache
deleteByXXX
という関数が軒並み消えていたんですね。
Result Cacheを使用する際に、IDに接頭語を付けて、前方一致で管理していたものが使えないといった感じです。
まぁ、ID管理じゃなくて、きちんとCacheにnamespace
を付けて管理してねということですね。
namespace
ごとにキャッシュクリア(deleteAll)したりできます。
今回は、Result Cacheに関して使い方を説明したいと思います。ほかのキャッシュ等の情報は下記参照。
Official(English)::doctrine-project — Caching
SymfonyでResultCacheを使用できるように設定する
まずは設定ですね。参考は下記です。
Official(English)::Configuration Reference — Cache Driver
Github::symfony / demo
様々カスタマイズできますが、サンプルとして、Githubのものをそのまま使用します。
doctrine: orm: auto_generate_proxy_classes: false metadata_cache_driver: type: pool pool: doctrine.system_cache_pool query_cache_driver: type: pool pool: doctrine.system_cache_pool result_cache_driver: type: pool pool: doctrine.result_cache_pool framework: cache: pools: doctrine.result_cache_pool: adapter: cache.app doctrine.system_cache_pool: adapter: cache.system
上記をdoctrine.yamlに記載したら設定は完了です。
Result Cache を使用する
Result CacheはDQL query
の結果をキャッシュすることが可能です。DQL query
を作成することで、関連メソッドが使用可能になります。
// Case Repository (extends ServiceEntityRepository) $qb = $this->createQueryBuilder('user') ->where('user.id = :id') ->setParameter('id', $userId); $qb->getQuery() ->useResultCache(true, 600, 'UserInfo') ->getResult();
getQuery()
でDQL queryが作成された後、関連メソッドが使用可能になります。
ResultCacheに格納するためにuseResultCache
を使用しています。
引数が三つありますが、各説明は下記です。
- [1]キャッシュドライバ
- TRUE: 既定のキャッシュドライバを使う
FALSE: キャッシュを利用しない
キャッシュドライバ指定 - [2]キャッシュの存続秒数
- 省略時はドライバのデフォルト値
- [3]ID
- 省略時は自動生成されるMD5ハッシュ値
その他メソッドは下記を参照してください。
https://doctrine2.readthedocs.io/en/latest/reference/caching.html
今回はまだnamespace
を指定していないので、namespaceが無いキャッシュが作成されます。
例えば、namespace
の指定なしで、deleteAll
すると、namespaceが無いキャッシュがすべて削除されます。
Result Cache を削除する
ResultCacheを削除する方法です。delete($id)
とdeleteAll
があります。
DQL queryからドライバを呼び出して削除します。
// Case Repository (extends ServiceEntityRepository) $qb = $this->getEntityManager()->createQuery(); $cacheDriver = $qb->getResultCacheDriver(); $cacheDriver->delete('UserInfo');
上記例だと、IDがUserInfo
のキャッシュが削除されます。簡単ですね。
さて、次は今回の私のテーマだった、ある特定のキャッシュだけをまとめて削除したい場合です。
doctrine1.xのときは、IDに接頭語を付けて、前方一致でdeleteByPrefix()
で削除していました。
その方法は使えなくなったので、namespace
でキャッシュを管理します。
namespaceを使用してresultCacheを管理する
簡単に言えば、namespaceという箱を作ってあげるだけですね。そこにキャッシュを格納していきます。
複数プロジェクトがあったり、User用のキャッシュ、Admin用のキャッシュなど区分けしたいときに便利です。
簡単なサンプルを紹介します。
// Case Repository (extends ServiceEntityRepository) // use ResultCashe in namespace "User" $qb = $this->createQueryBuilder('user') ->where('user.id = :id') ->setParameter('id', $userId) ->getQuery(); $cacheDriver = $qb->getResultCacheDriver(); $cacheDriver->setNamespace('User'); $result = $qb->useResultCache(true, 600, 'UserInfo') ->getResult(); // DeleteAll namespace "User" $qb = $this->getEntityManager()->createQuery(); $cacheDriver = $qb->getResultCacheDriver(); $cacheDriver->setNamespace('User'); $cacheDriver->deleteAll();
キャッシュドライバを呼び出し、setNamespace()
でDQL queryに対してnamespaceを設定しています。
上記コードでdeleteAllを実行した場合、namespaceが「User」であるキャッシュ群が削除されます。
以上簡単ですが、resultCacheの使い方とnamespaceの設定の仕方についてまとめてみました。
細かいところは、文中で紹介したURLから見ていただいたほうがよいと思います。
Symfonyおすすめ書籍
あまり種類がないのと、そもそもフレームワークとして情報が膨大なので、入門でも結構読み応えがあります。
「PHPフレームワーク Symfony 4入門」