by shigemk2

当面は技術的なことしか書かない

CakePHP 2 to 3 find結果をキャッシュする

キャッシュに書き込むときはCache::writeをつかえばいいんだけど、

CakePHP ORM で作成したクエリーの結果をキャッシュする場合は、 ロードされた結果をキャッシュする セクションで説明しているように、Query オブジェクトのビルトインキャッシュ機能を使用する方が良いです。

ドキュメントにはこういったことが書いてあるし、find結果のORMオブジェクトをそのままCache::writeしようとすると PDOException: You cannot serialize or unserialize PDO instances が出てしまう。toArrayすればCache::writeできるけど、toArrayしたものを元に戻す方法がないしfindするたびに毎回toArrayするのも現実的じゃないから、やっぱりビルトインのcache機能を使えばいいと思う。

if (($posts = Cache::read('posts')) === false) {
    $posts = $someService->getAllPosts();
    Cache::write('posts', $posts);
}

ただ、簡単な名前のキーじゃなくって、whereやjoiinの内容をmd5でハッシュ化した文字列をキーにすることもできる。

// クエリーの where 句の単純なチェックサムに基づくキーを生成します
$query->cache(function ($q) {
    return 'articles-' . md5(serialize($q->clause('where')));
});

こんな感じでキャッシュをグループ分けすると、afterSaveなどで消しやすくなるから便利かも。

// クエリーの where 句の単純なチェックサムに基づくキーを生成します
$query->cache(function ($q) {
    return 'articles-' . md5(serialize($q->clause('where')));
}, 'article-group1');

afterSaveなどで後始末する。

public function afterSave($event, $entity, $options = [])
{
    if ($entity->isNew()) {
        Cache::clearGroup('article-group1');
    }
}

book.cakephp.org

book.cakephp.org