1 use Symfony\Component\EventDispatcher\EventDispatcher; 2 3 $dispatcher = new EventDispatcher();
1 $listener = new AcmeListener(); 2 $dispatcher->addListener('foo.action', array($listener, 'onFooAction'));
PHP callable是指能做爲參數傳入call_user_func()或者傳入is_callable()函數執行後返回true的PHP 變量。PHP callable能夠是 \Closure實例,一個實現了__invoke方法的對象,或者是表示一個函數的字符串,或者一個表示對象方法或者類方法的數組。到目前爲止,咱們看過把一個PHP對象做爲監聽器,咱們也能夠把Closure對象做爲監聽器。1 use Symfony\Component\EventDispatcher\Event; 2 3 $dispatcher->addListener('foo.action', function (Event $event) { 4 // will be executed when the foo.action event is dispatched 5 });
1 use Symfony\Component\EventDispatcher\Event; 2 3 class AcmeListener 4 { 5 // ... 6 7 public function onFooAction(Event $event) 8 { 9 // ... do something 10 } 11 }
在實際使用中,都是傳入一個特定的Event子類的對象到監聽器,例如FilterResponseEvent:數組
1 use Symfony\Component\HttpKernel\Event\FilterResponseEvent; 2 3 public function onKernelResponse(FilterResponseEvent $event) 4 { 5 $response = $event->getResponse(); 6 $request = $event->getRequest(); 7 8 // ... 9 }
namespace Acme\StoreBundle; final class StoreEvents { /** * The store.order event is thrown each time an order is created * in the system. * * The event listener receives an * Acme\StoreBundle\Event\FilterOrderEvent instance. * * @var string */ const STORE_ORDER = 'store.order'; }
1 namespace Acme\StoreBundle\Event; 2 3 use Symfony\Component\EventDispatcher\Event; 4 use Acme\StoreBundle\Order; 5 6 class FilterOrderEvent extends Event 7 { 8 protected $order; 9 10 public function __construct(Order $order) 11 { 12 $this->order = $order; 13 } 14 15 public function getOrder() 16 { 17 return $this->order; 18 } 19 }
1 use Acme\StoreBundle\StoreEvents; 2 use Acme\StoreBundle\Order; 3 use Acme\StoreBundle\Event\FilterOrderEvent; 4 5 // the order is somehow created or retrieved 6 $order = new Order(); 7 // ... 8 9 // create the FilterOrderEvent and dispatch it 10 $event = new FilterOrderEvent($order); 11 $dispatcher->dispatch(StoreEvents::STORE_ORDER, $event);
FilterOrderEvent對象做爲參數傳入到dispatch方法,如今,任何監聽store.order事件的監聽器都會接收到FilterOrderEvent對象,並經過調用getOrder方法得到order對象。緩存
1 // some listener class that's been registered for "store.order" event 2 use Acme\StoreBundle\Event\FilterOrderEvent; 3 4 public function onStoreOrder(FilterOrderEvent $event) 5 { 6 $order = $event->getOrder(); 7 // do something to or with the order 8 }
namespace Acme\StoreBundle\Event; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; class StoreSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents() { return array( 'kernel.response' => array( array('onKernelResponsePre', 10), array('onKernelResponseMid', 5), array('onKernelResponsePost', 0), ), 'store.order' => array('onStoreOrder', 0), ); } public function onKernelResponsePre(FilterResponseEvent $event) { // ... } public function onKernelResponseMid(FilterResponseEvent $event) { // ... } public function onKernelResponsePost(FilterResponseEvent $event) { // ... } public function onStoreOrder(FilterOrderEvent $event) { // ... } }
這個監聽器類很簡單,告訴了dispatcher監聽了什麼事件,還有監聽的事件觸發的方法。addSubscriber()方法把subscriber註冊到dispatcher。函數
1 use Acme\StoreBundle\Event\StoreSubscriber; 2 3 $subscriber = new StoreSubscriber(); 4 $dispatcher->addSubscriber($subscriber);
onKernelResponsePre
,
onKernelResponseMid
, 和
onKernelResponsePost三個方法就會前後執行。
1 use Acme\StoreBundle\Event\FilterOrderEvent; 2 3 public function onStoreOrder(FilterOrderEvent $event) 4 { 5 // ... 6 7 $event->stopPropagation(); 8 }
1 $dispatcher->dispatch('foo.event', $event); 2 if ($event->isPropagationStopped()) { 3 // ... 4 }