📜 ⬆️ ⬇️

PSR-14 - the main event in PHP

Last year, PHP-FIG - The PHP Compatibility Concepts Group, has released several new specifications. The last one, PSR-14 , is dedicated to event scheduling. Like other PSRs, this is a local specification, but has a great influence on many aspects of standardization.

From the translator: This is the translation of the first part of a series of publications in which Larry (Crell) Garfield, one of the members of PHP-FIG, explains what PSR-14 is, what it can do and what it doesn’t, and how best to use it in their projects.

purpose


Event dispatch has long been used in many languages. If you have ever used EventDispatcher in Symfony , Event system in Laravel , hooks in Drupal, Event Manager in the Zend framework, League \ Event package, or something similar, then you know what this is about.

In a general sense, all these systems are a form of "observer-mediator". One code fragment sends a message of the type - “event”, and the intermediary sends it to other separate code fragments - “listeners”. Sometimes the signal is directed only in one direction, sometimes the “listener” can somehow transmit data back to the caller. Of course, they are all different and not very compatible with each other.
')
This is a problem for standalone libraries that want to connect to different libraries and applications. Many libraries can be expanded by sending events in one form or another, so that other code can link to them. But such an intermediary layer is, in fact, proprietary. The library that runs the symfony eventDispatcher is then merged with symfony. Then using it somewhere else requires installing an EventDispatcher and connecting to libraries in the program. The library that calls the binding system from Drupal module_invoke_all() , then links to Drupal. And so on.

The purpose of PSR-14 is to rid the library of this dependency. This allows libraries to expand through a thin common layer, and then facilitate their transfer to another environment without additional efforts and costs, for example, in Symfony, Zend Framework, Laravel, TYPO3, eZ Platform or Slim. As long as the medium has compatibility with the PSR-14, everything will work.

Specification


As already mentioned, the specification is quite easy. These are three interfaces in one method and a meta description of how to use them. Everything is simple and convenient. Below is the code of these interfaces (no comments to save space).

 namespace Psr\EventDispatcher; interface EventDispatcherInterface { public function dispatch(object $event); } interface ListenerProviderInterface { public function getListenersForEvent(object $event) : iterable; } interface StoppableEventInterface { public function isPropagationStopped() : bool; } 

The first two are the core specifications. StoppableEventInterface is an extension to which we return later.

I think EventDispatcher familiar to most of you - it’s just an object with a method to which you transmit an event - an intermediary, which we have already spoken about. The event itself, however, is not defined - it can be any PHP object . More on this later.

Most existing implementations have one object or set of functions that act as an intermediary or dispatcher and a place to register the code that receives the event (listeners). For PSR-14, we consciously divided these two responsibilities into separate objects. The dispatcher receives a list of listeners from the supplier object that makes this list.

Where does the provider get the list of listeners then? Yes, where he wants from! There is a billion and one ways to connect the listener and the event, they are all absolutely valid and incompatible. At the beginning, we decided that the standardization of the “One True Way” of registering listeners would be too limited. However, by standardizing the process of connecting the listener to the dispatcher, you can get excellent flexibility without forcing the user to do something strange and incomprehensible.

Also, the code does not indicate what the listener is. It can be any PHP-capable fragment of a signal: a function, an anonymous function, an object method, anything. Since the callee can do anything, it means that it is acceptable to have as a listener, say, an anonymous function that performs a deferred loading of the service from the DI container and calls the service method, which actually contains the listening code.

In short, a dispatcher is a simple and easy API for library authors. Listener vendors offer a robust and flexible API for framework integrators, and the relationship between the controller and the provider brings them together.

Simple example


In general terms, the scheme of combining all the parts into a whole will look something like this.

 class Dispatcher implements EventDispatcherInterface { public function __construct(ListenerProviderInterface $provider) { $this->provider = $provider; } public function dispatch(object $event) { foreach ($this->provider->getListenersForEvent($event) as $listener) { $listener($event); } return $event; } } $dispatcher = new Dispatcher($provider); $event = new SomethingHappened(); $dispatcher->dispatch($event); 

This small piece of code opens up great possibilities, and it is very flexible. In the following articles we will talk in detail about its properties, analyze some structural solutions and consider the sets of ways to use such lightweight events.

Code


PSR-14 is already supported by main frameworks and applications.


PSR-14 also has three fully-functional independent implementations that you can already use in any application.


The author thanks the entire PSR working group: Larry Garfield , Cees-Jan Kiewiet , Benjamin Mack , Elizabeth Smith , Ryan Weaver , Matthew Weier O'Phinney . Throughout the work, the process was highly productive: everyone worked together, collectively, as it should be. The result is good, and we would like all further efforts in joint work on the architecture to be just as productive.

You can learn more details either from the original of the next part and the documentation or on May 17 at PHP Russia . The second option is attractive for several reasons. For example, the head of the Program Committee, Alexander ( samdark ) Makarov, is among those who have implemented PSR-14 in Yii. And in principle, the composition of the Program Committee and the speakers is incredibly strong, there is hardly any topic from the sphere of professional use of PHP that cannot be discussed at this conference.

Source: https://habr.com/ru/post/450812/


All Articles