PHPでイベントドリブンしてみる
Pearのパッケージを眺めてたら、Event_Dispatcherというのを発見。
そそられたものの、サンプル見てみると自分が適当に使う分には少し手続きが煩雑な気がするなーと思ったので簡単なのを自分で書いてみることにした。
ソース
<?php // event_dispatcher.php class Event{ const ALL_EVENTS = 'allEvents'; const SOME_EVENT = 'someEvent'; } class EventListener{ public $event_type; public $func; public static $listeners = array(); function __construct( $e, $f){ $this->event_type = $e; $this->func = $f; } } function addEventListener( $event_type, $func){ $listeners = &EventListener::$listeners; $listeners[] = new EventListener( $event_type , $func); } function removeEventListener( $event_type, $func){ $listeners = &EventListener::$listeners; foreach( $listeners as $key => &$listener){ if( $listener->func === $func || $event_type === $listener->event_type){ unset( $listeners[$key]); } } } function dispatchEvent( $event_type, $info = array()){ $listeners = &EventListener::$listeners; foreach( $listeners as &$listener){ if( $listener->event_type === Event::ALL_EVENTS ||$event_type === $listener->event_type){ call_user_func( $listener->func, $info); } } }
サンプル
<?php // sample.php require 'event_dispatcher.php'; addEventListener( Event::ALL_EVENTS, 'onAllEvents'); addEventListener( Event::SOME_EVENT, 'onSomeEvent'); echo "dispatch ALL_EVENTS\n"; dispatchEvent( Event::ALL_EVENTS); echo "\n"; echo "dispatch SOME_EVENT\n"; dispatchEvent( Event::SOME_EVENT); echo "\n"; echo "dispatch SOME_EVENT\n"; dispatchEvent( Event::SOME_EVENT); //--- function onAllEvents( $info){ static $i = 0; $i++; echo "これは{$i}回目のEvent::ALL_EVENTSです\n"; } function onSomeEvent( $info){ echo "これは一回限定のEvent::SOME_EVENTです\n"; removeEventListener( EVENT::SOME_EVENT, 'onSomeEvent'); }
上記サンプルの実行結果
dispatch ALL_EVENTS これは1回目のEvent::ALL_EVENTSです dispatch SOME_EVENT これは2回目のEvent::ALL_EVENTSです これは一回限定のEvent::SOME_EVENTです dispatch SOME_EVENT これは3回目のEvent::ALL_EVENTSです