Hello, everyone. This article will introduce the use and implementation of the EventDispatcher component of Symfony by using examples from my actual development work.

This component is very useful in the actual development process. It can make the business logic of the code very clear, increase the reusability of the code, and greatly reduce the coupling of the code.

Introduction to the

Specific introduction you can view the official document, the following is the document address.

The document address

composition

  • A Dispatcher object that holds the name of the event and its corresponding listener
  • An event with a globally unique event name. Contains objects that you need to access in the subscriber.

Use the sample

1. Initialize and add corresponding listening events
$dispatcher = new EventDispatcher(); $disptacher->addSubscriber(new BIReportSubscriber()); $disptacher->addSubscriber(new MediaPlayerSubscriber()); // Maintain player information unity
  1. Symfony\Component\EventDispatcher\EventDispatcher
2. Monitoring events
class BIReportSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents () { // Listen for different events, and when the event is triggered, Will call onResponse method return [MusicResponseEvent: : NAME = > 'onResponse, ChildrenResponseEvent: : NAME = >' onResponse ', FmResponseEvent::NAME => 'onResponse', NewsResponseEvent::NAME => 'onResponse', ]; } public function onResponse($event, $event, $event, $event, $event, $event, $event, $event) {
class MediaPlayerSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents () { return  [ MusicResponseEvent::NAME => 'onResponse', FmResponseEvent::NAME => 'onResponse', ChildrenResponseEvent::NAME => 'onResponse', NewsResponseEvent::NAME => 'onResponse', ]; } public function onResponse($event, $event, $event, $event, $event, $event, $event, $event) {
  1. implementationgetSubscribedEventsMethod to complete the binding of the event. When the event fires, the Dispatcher calls the bound method and passes in the thrown event as a parameter.
  2. Method of event bindingonResponseIt could be anything.
  3. inonResponseMethod, through$eventGets the object to operate on.
3. Event code
class FmResponseEvent extends Event { const NAME = 'fm.response'; Protected $request; // protected $request; Protected $response; // the object in the listener that you want to operate on Public function __construct (Request $Request, Response $Response) {$this-> Request = $Request; $this-> Request = $Request; $this->response = $response; } /** * @return Request */ public function getRequest() { return $this->request; } /** * @return Response */ public function getResponse() { return $this->response; }}
  1. inheritanceSymfony\Component\EventDispatcher\Event
  2. On the subscriber’s business logic, you need to use$$response and requestObject, so this event contains objects of both classes.
4. Trigger events
 $event = new FmResponseEvent($request, $response);
 $dispatcher->dispatch($event::NAME, $event);
  1. dispathcerEvent binding methods in the subscriber are executed in order of priority

The original code reading

Simplified EventDispatcher source code
class EventDispatcher implements EventDispatcherInterface { private $listeners = array(); private $sorted = array(); /** * public function dispatch($function name, $function name, $function name) Event $event) { if ($listeners = $this->getListeners($eventName)) { $this->doDispatch($listeners, $eventName, $event); } return $event; } /** * According to the event name, / Listeners/Listeners/Listeners/Listeners/Listeners/Listeners/Listeners/Listeners/Listeners } if (! isset($this->sorted[$eventName])) { $this->sortListeners($eventName); } return $this->sorted[$eventName]; } /** * Listeners($listenerListeners, $listListeners, $listListeners, $listListeners, $listListeners); krsort($this->listeners[$eventName]); $this->sorted[$eventName] = array(); foreach ($this->listeners[$eventName] as $priority => $listeners) { foreach ($listeners as $k => $listener) { if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) { $listener[0] = $listener[0](); $this->listeners[$eventName][$priority][$k] = $listener; } $this->sorted[$eventName][] = $listener; } } } protected function doDispatch($listeners, $eventName, Event $event) { foreach ($listeners as $listener) { if ($event->isPropagationStopped()) { break; } \call_user_func($listener, $event, $eventName, $this); } public function addSubscriber(eventSubscriberInterface $Subscriber) {foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { if (is_string($params)) { $this->addListener($eventName,  array($subscriber, $params)); } elseif (is_string($params[0])) { $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0); } else { foreach ($params as $listener) { $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0); } } } } public function addListener($eventName, $listener, $priority = 0) { $this->listeners[$eventName][$priority][] = $listener; unset($this->sorted[$eventName]); }}