The Symfony EventDispatcher component is among the simplest yet extensively used both by Symfony itself and by application code. Its function is very simple: there is one central
EventDispatcherInterface service, which can dispatch arbitrary events (defined by name and optionally by an instance of
Event-derived class), and register listeners for these events. EventDispatcher is invaluble in writing extensible, loosely coupled code.
A good example of EventDispatcher use is Symfony’s central
HttpKernel class, which, as we saw before, transforms a HTTP
Request into a
Response. It does that by resolving and executing a controller function. Controllers are typically mapped to URLs via Routing component; however
HttpKernel is entirely unaware of Routing classes and their implementation. Instead there is a
RouterListener class which glues Routing to
HttpKernel by locating appropriate controller name, and setting
_controller attribute on
Request (or throwing a
NotFoundHttpException if no routes match the request).
HttpKernel may then resolve controller name to an actual controller function and its arguments using default
ControllerResolverInterface implementation, and call this function to render a
That’s all fine and good, but sizable legacy applications attempting to be somewhat extensible typically implement some kind of events/hooks/whatever-they-call-it system themselves. So can we route the legacy hook APIs through EventDispatcher? Why of course we can.