CakePHP 3 でクエリ結果をキャッシュする
はじめに
CakePHP 3 にはキャッシュ機能が整備されています。公式のCookbookにも、クエリの結果を簡単にキャッシュできるという説明がありました。
- ロードされた結果をキャッシュする (CakePHP 3 Cookbook)
- https://book.cakephp.org/3.0/ja/orm/query-builder.html#caching-query-results
しかし「簡単」なためか、説明が非常にシンプルで、一見どんな挙動になるのかイメージできませんでした。そこで実際にサンプルプログラムを作って調べたので、今日はその結果をご紹介します。
今回使用した CakePHP のバージョンは 3.8.3 です。
1. 本当に簡単だった実装方法
データベースに、都道府県の id と name を入れた prefectures テーブルを作成し、そのリスト配列を取得するコードをつくって試しました。
最初に行ったのは、上記 Cookbook の説明にある ->cache('●●●') の追加です。
public function index()
{
$this->loadModel('Prefectures');
$prefList = $this->Prefectures->find('list')
->cache('pref_list') // ← これを追加
->toArray();
$this->set(compact('prefList'));
}
これだけでキャッシュが有効になりました。確認は CakePHP3 の Debug Kit にある「SqlLog」画面で行えます。
初回はクエリが実行されてSQL文が表示されましたが、ブラウザの更新ボタンを押すとクエリは実行されず、「No active database connections」と出ました。キャッシュファイルを手動で削除すると再度実行されますので、実際に操作して試してみてください。
キャッシュファイルのパスは下記になります。
(設定を変更していなければ)
tmp/cache/cake_pref_list
キャッシュの設定は config/app.php にあります。
/**
* Configure the cache adapters.
*/
'Cache' => [
'default' => [
'className' => FileEngine::class,
'path' => CACHE,
'url' => env('CACHE_DEFAULT_URL', null),
],
// ~~~ 省略 ~~~
],
今回追記した ->cache('pref_list') では、この 'default' 設定が読み込まれていて、その中にある 'path' の CACHE 定数が tmp/cache を指しています。
2. 設定の追加
キャッシュの設定は、下記のように自分で追加することができます。
'Cache' => [
'default' => [
'className' => FileEngine::class,
'path' => CACHE,
'url' => env('CACHE_DEFAULT_URL', null),
],
// ▼これを追加
'mycache' => [
'className' => FileEngine::class,
'path' => CACHE . DS . 'mycache', // ← パスを変更
'duration' => '+1 min', // ← キャッシュの有効期限を追加
'url' => env('CACHE_DEFAULT_URL', null),
],
// ~~~ 省略 ~~~
],
クエリ結果をキャッシュする際に、この「mycache」設定を用いるためには、下記のように第二引数で指定します。
public function index()
{
$this->loadModel('Prefectures');
$prefList = $this->Prefectures->find('list')
->cache('pref_list', 'mycache') // ← 第二引数で設定を指定
->toArray();
$this->set(compact('prefList'));
}
この画面を閲覧した際に作られるキャッシュファイルのパスは以下になります。
tmp/cache/mycache/cake_pref_list
今回は設定で duration を追記しています。キャッシュが有効であることを確認したあとで、「1分」待ってからページ再読込を行い、 SqlLog を確認したところ、クエリが実行されていました。
(1分以内であればクエリは実行されません)
この duration は PHP の strtotime() 関数と同じ表記で指定できます。
- PHP: strtotime - Manual
- https://www.php.net/manual/ja/function.strtotime.php
3. おわりに
実際に手を動かして確かめることで、キャッシュ関連の設定方法などをつかむことができました。
デフォルトの File キャッシュは簡単に導入でき、シンプルで分かりやすいです。
他にもキャッシュエンジンはありますが、まずはこの File キャッシュを使って効率化できるところはないか、検討と試行をしてみるのもいいと思います。
たとえば、例でも用いた都道府県など変更の少ないデータの取得や、追加/更新の頻度が低いデータの集計などに用いると効果的ではないかと考えています。
- CakePHP 3 に用意されているキャッシュエンジン (CakePHP 3 Cookbook)
- https://book.cakephp.org/3.0/ja/core-libraries/caching.html#namespace-Cake\Cache