【CakePHP4入門】モデル:ビヘイビアーのイベントリスナー

CakePHP4のビヘイビアーのイベントリスナーとは

今回はビヘイビアーのイベントリスナーについてみていきます。

ビヘイビアーについてはこちらの記事をご参考ください。
参考 【CakePHP4入門】モデル:ビヘイビアー

Cakephp4のTableクラスは関連するテーブルに対してinsert,update,delete,selectといったSQLを実行します。
こういったいくつかの挙動をイベントといい、そのイベントが発生するタイミングで何か処理を行うことにしたい場合、そのイベントが発生したときに実行する処理をメソッドとして定義しておくことができます。

CakePHP4のモデルのイベントには以下のようなものがあるとのこと。

  • initialize
  • beforeMarshal
  • beforeFind
  • buildValidator
  • buildRules
  • beforeRules
  • afterRules
  • beforeSave
  • afterSave
  • afterSaveCommit
  • beforeDelete
  • afterDelete
  • afterDeleteCommit

詳細は以下のCakePHPの公式ドキュメントをご参考ください。
参考 イベント一覧

この各イベントを検出するイベントリスナーをTableクラスに用意しておくことができます。
例えばbeforeSaveメソッドのコールバックメソッドを以下のように作成しておけば、

public function beforeSave($event, $entity, $options)
{
    //処理
}

そのTableがsave(レコードのinsert)を実行する直前に、上記の処理を実行させることができるようになります。
そしてこのイベントリスナーはビヘイビアにも設定することができます。

今回は「beforeFind」で、findメソッドが呼び出される際に常に「order([‘created’=>’DESC’])」を付与するという設定をしていきます。

CakePHP4のビヘイビアにイベントリスナーを設定

「Model/Behavior」ディレクトリの下に「OrderDescBehavior」を作成してみます。
そして、以下のメソッドを追加します。

public function beforeFind(Event $event ,Query $query, $options, $primary) {
    $query->order(['created'=>'DESC']);
    return $query;
}

上記のメソッドは、findメソッドが実行される直前に、「created」カラム降順にする「order by」句を追加する、という内容になります。
「beforeFind」は、「findの直前」のイベントということです。引数に何がくるのかはイベントごとに決まっており、今回のbeforeFindは上記の引数になっています。「$query」は実行しようとしているクエリオブジェクトになりますので、$queryにorderを追加しているということになります。

ではこのビヘイビアをSamplesTableクラスに追加しましょう。
SamplesTable.phpのinitializeメソッドに以下の記述を追加します。

$this->addBehavior('OrderDesc');

こうすることで、Controller側から以下のようにSamplesのfindメソッドを呼び出すと、そのタイミングで「order(‘created’=>’DESC’)」が付加されるようになります。例えController側でorderの設定をしていなかったとしても、実行されるSQLには「order by created desc」が付加されていることになるのです。

このビヘイビアを別のテーブルに追加しておけば、そのテーブルでも必ずfindする際にcreated降順にすることができます。
こういった複数のテーブルで同じ処理をしたい場合に、各テーブルクラスでその記述をするのではなく、ビヘイビアのイベントリスナーに設定するというのもビヘイビアーの便利な使い方の1つになります。