php EventManager Module
zf 2のEventManagerを参考に、実際のプロジェクトのニーズに合わせて簡単なEventManagerを書きました.主な機能は以下のとおりです.購読者モード; ブロック; イベント駆動 具体的な概念は紹介しません.まずモジュールのいくつかのクラスやインタフェースを見てみましょう.
EventManagerは、主にイベントのリスニング、ブロッキングの追加、イベントのトリガーを担当するコアモジュールです.次の例を示します.
出力結果は、the parameter is{“foo”:“bar”,“baz”:“bat”}
attachメソッドのプロトタイプは次のとおりです.
3つのパラメータは、次のとおりです.は、複数のイベント名からなる配列であってもよく、イベント名にワイルドカードを含むことができるリスニングを必要とするイベント名である. リスナー、いかなる合法的なPHPコールバックもリスナーとすることができる. 優先度は、1つのイベントに複数のListenerがある場合に優先度の高いListenerが先にトリガーされます.
InterceptorInterfaceインタフェース
ブロッカーが実装する必要がある2つの方法を定義します:beforeとafter、beforeメソッドはリスナーより先に呼び出され、afterメソッドは最後に呼び出されます.例は次のとおりです.
出力結果:before sta*start after
またListenerクラスとStaticEventManagerもあり、後者はグローバルなEventManagerであり、具体的にはコードを表示することができます.
交流を歓迎します.もっと良いアドバイスがあれば、教えてください.
EventManagerは、主にイベントのリスニング、ブロッキングの追加、イベントのトリガーを担当するコアモジュールです.次の例を示します.
<?php
require 'EventManager.php';
$em = new EventManager();
$em->attach('start', function ($e) {
printf('the parameter is %s', json_encode($e));
});
$params = array('foo' => 'bar', 'baz' => 'bat');
$em->trigger('start', $params);
出力結果は、the parameter is{“foo”:“bar”,“baz”:“bat”}
attachメソッドのプロトタイプは次のとおりです.
/**
* attach a listener to an event
*
* @param $event string|array
* @param $callback callable
* @param $priority int
*/
public function attach($event,$callback,$priority=1)
{
if(is_array($event))
{
foreach($event as $name)
{
$this->attach($name,$callback,$priority);
}
return;
}
if(!$this->events[$event])
$this->events[$event] = array();
if(!$this->events[$event][self::LISTENER])
$this->events[$event][self::LISTENER] = new SplPriorityQueue();
$listener = new Listener($event,$callback,intval($priority));
$this->events[$event][self::LISTENER]->insert($listener,$priority);
}
3つのパラメータは、次のとおりです.
InterceptorInterfaceインタフェース
ブロッカーが実装する必要がある2つの方法を定義します:beforeとafter、beforeメソッドはリスナーより先に呼び出され、afterメソッドは最後に呼び出されます.例は次のとおりです.
<?php
class Interceptor implements InterceptorInterface
{
public function before($e = null)
{
printf('before ');
}
public function after($e = null)
{
printf('after ');
}
}
require 'EventManager.php';
$em = new EventManager();
$em->attach('start', function ($e) {
printf('start ');
});
$em->attach('sta*', function ($e) {
printf('sta* ');
}, 3);
$em->intercept('start', new Interceptor());
$em->trigger('start');
出力結果:before sta*start after
またListenerクラスとStaticEventManagerもあり、後者はグローバルなEventManagerであり、具体的にはコードを表示することができます.
<?php
interface InterceptorInterface
{
public function before();
public function after();
}
class Listener
{
protected $event = null;
protected $callback = null;
protected $priority = 1;
public function __CONSTRUCT($event, $callback, $priority)
{
$this->event = $event;
$this->callback = $callback;
$this->priority = $priority;
}
public function setEvent($event)
{
$this->event = $event;
}
public function getEvent()
{
return $this->event;
}
public function setCallBack($callback)
{
$this->callback = $callback;
}
public function getCallBack()
{
return $this->callback;
}
public function setPriority($priority)
{
$this->priority = $priority;
}
public function getPriority()
{
return $this->priority;
}
}
class StaticEventManager
{
protected static $instance = null;
protected function __CONSTRUCT()
{
}
static public function ins()
{
if (self::$instance === null) {
self::$instance = new EventManager();
}
return self::$instance;
}
}
class EventManager
{
/**
* type
*/
const LISTENER = 0;
const INTERCEPTOR = 1;
/**
* Subscribed events and their listeners and interceptors
*/
protected $events = array();
/**
* intercept the event with an interceptor
*
* @param $event string|array
* @param $interceptor InterceptorInterface
*/
public function intercept($event, InterceptorInterface $interceptor)
{
if (is_array($event)) {
foreach ($event as $name) {
$this->Intercept($name, $interceptor);
}
return;
}
if (!isset($this->events[$event]))
$this->events[$event] = array();
if (!isset($this->events[$event][self::INTERCEPTOR]))
$this->events[$event][self::INTERCEPTOR] = array();
$this->events[$event][self::INTERCEPTOR][] = $interceptor;
}
/**
* attach a listener to an event
*
* @param $event string|array
* @param $callback callable
* @param $priority int
*/
public function attach($event, $callback, $priority = 1)
{
if (is_array($event)) {
foreach ($event as $name) {
$this->attach($name, $callback, $priority);
}
return;
}
if (!isset($this->events[$event]))
$this->events[$event] = array();
if (!isset($this->events[$event][self::LISTENER]))
$this->events[$event][self::LISTENER] = new SplPriorityQueue();
$listener = new Listener($event, $callback, intval($priority));
$this->events[$event][self::LISTENER]->insert($listener, $priority);
}
/**
* trigger listeners of an event
*
* @param $event string|array
* @param $params
*/
public function trigger($event, $params = null)
{
if (is_array($event)) {
foreach ($event as $name) {
$this->trigger($name, $callback, $priority);
}
return;
}
$matchEvents = $this->getMatchEvents($event);
$interceptors = array();
$listeners = new SplPriorityQueue();
foreach ($matchEvents as $e) {
$interceptors = array_merge($interceptors, $this->getInterceptors($e));
$this->insertListeners($listeners, $this->getListeners($e));
}
foreach ($interceptors as $interceptor) {
$interceptor->before($params);
}
$this->triggerListeners($listeners, $params);
foreach ($interceptors as $interceptor) {
$interceptor->after($params);
}
}
/**
* retrieve all registered events
*
* @return array
*/
public function getEvents()
{
return array_keys($this->events);
}
/**
* retrieve all matched events for a given event
*
* @return array
*/
public function getMatchEvents($event)
{
$allEvents = $this->getEvents();
$matchEvents = array();
foreach ($allEvents as $key) {
if (preg_match('/' . $key . '/i', $event)) {
$matchEvents[] = $key;
}
}
return $matchEvents;
}
/**
* retrieve all listeners for a given event
*
* @param $event string
* @return SplPriorityQueue
*/
public function getListeners($event)
{
$listeners = new SplPriorityQueue();
if ($this->events[$event][self::LISTENER])
$listeners = $this->events[$event][self::LISTENER];
return $listeners;
}
/**
* retrieve all interceptors for a given event
*
* @param $event string
* @return array
*/
protected function getInterceptors($event)
{
$interceptors = array();
if (isset($this->events[$event][self::INTERCEPTOR]))
$interceptors = $this->events[$event][self::INTERCEPTOR];
return $interceptors;
}
/**
* Trigger listeners
*
* @param $listeners array
* @param $params
*/
protected function triggerListeners($listeners, $params = null)
{
foreach ($listeners as $listener) {
call_user_func($listener->getCallBack(), $params);
}
}
/**
* Add listeners to the master queue of listeners
*
* @param PriorityQueue $masterListeners
* @param PriorityQueue $listeners
* @return void
*/
protected function insertListeners($masterListeners, $listeners)
{
if (!count($listeners)) {
return;
}
foreach ($listeners as $listener) {
$priority = $listener->getPriority();
if (null === $priority) {
$priority = 1;
}
$masterListeners->insert($listener, $priority);
}
}
}
交流を歓迎します.もっと良いアドバイスがあれば、教えてください.