logo

モデルのイベント間で値を共有する方法

CakePHPにおいてモデルの各イベント間で値を共有したい場面がたまにある。
たとえば、 beforeSave でしか取得できない値を afterSave で使いたいとか、エンティティの値によって buildRules のルールに値を渡したいなど。

そういう場合、以下の方法で値の受け渡しができるようになる:

// モデル内で public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) { $options['hogehoge'] = 'hugahuga'; } public function afterSave(Event $event, EntityInterface $entity, ArrayObject $options) { debug($options['hogehoge']); // => 'hugahuga'; }

各イベントの $options はイベント間で同じものが使いまわされているため、先に発生するイベントで追加された値は、後のイベントで利用できるようになる。
上記の例では、 beforeSave で追加した $options['hogehoge']afterSave で利用できるようになっている。

また、この $optionsルールチェッカー$rules->add の引数としても利用されているため、そこでも利用できる。

public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) { $options['foo'] = true; } public function buildRules(RulesChecker $rules) { $rules->add(function ($entity, $options) { debug($options['foo']); // => true; }, 'ruleName'); return $rules; }

上記の例では、単純に固定値を設定しているだけだが、複数のルールで同じモデルの同じレコードを参照しないといけない場合など、あらかじめ beforeSave などで、その共通で参照しないといけないデータを取得して $options に追加しておけば、ルール毎にfindする必要がなくなり、多少は高速化が見込める。
同じコードを何度も書く必要がなくなり、見通しがよくなるはず。