CakePHP 4: イベントシステムの概要

概要

  • CakePHPのイベントシステム

    • モデル・ビヘイビアー・コントローラー・ビュー・ヘルパーのコールバックの心臓部
    • why
      • クラスの結合度を下げる
      • コードの関心事を明確に分離させる
    • how
      • Observer パターン
        • オブジェクトがイベントを発行し、リスナーに対して、状態変化を通知するパターン
  • イベント

    • Cake\Event\EventInterface を実装したクラスのインスタンス
    • 全てのイベントリスナーに行き渡る
      • イベントに関する情報を持ち、任意のポイントでイベントの伝播を止めることができる
  • コアイベント

  • イベントリスナー

    • Cake\Event\EventListenerInterface を実装したクラスのインスタンス
    • イベント毎の処理を実装する
    • イベントを受信し、イベントに応じた処理を実行する

サンプル

リスナーの実装

use Cake\Event\EventListenerInterface;

// イベント毎のcallbackを登録したいクラスに対し、EventListenerInterface インターフェイスを実装
class HogeLister implements EventListenerInterface
{
    // HogeLister が処理するイベント名を定義
    public function implementedEvents()
    {
        return [
            'Model.Order.afterPlace' => 'doHoge',
        ];
    }

    // Model.Order.afterPlace イベント受信時に実行する処理
    public function doHoge($event, $order)
    {
        // ...
    }
}

リスナーの登録

// イベントリスナーを生成
$hogeListener = new HogeListener();

// Orderモデルの EventManager にリスナーを登録
$this->Orders->getEventManager()->on($hogeListener);

イベントのディスパッチ

use Cake\Event\Event;

// カートシステム の 注文モデル
class OrdersTable extends Table
{
    // 注文の作成
    public function place($order)
    {
        // 注文の作成
        if ($this->save($order)) {
            // カートを空にする
            $this->Cart->remove($order);

            /**
             * イベントを発行し、リスナーに通知
             */
            // イベントオブジェクト(afterPlaceイベント)を生成
            $event = new Event('Model.Order.afterPlace', $this, [
                'order' => $order
            ]);
            // リスナーにイベントを通知
            //   この例では、Orderモデルの EventManager に HogeLister が登録されているので、
            //   Model.Order.afterPlaceイベントに対応する処理(=HogeLister::doHoge)が実行される
            $this->getEventManager()->dispatch($event);
            return true;
        }
        return false;
    }
}