Skip to content

Instantly share code, notes, and snippets.

@sagikazarmark
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sagikazarmark/daf7f03aa3856aa26e8f to your computer and use it in GitHub Desktop.
Save sagikazarmark/daf7f03aa3856aa26e8f to your computer and use it in GitHub Desktop.
Event Interop Interfaces
# Emitter/Dispatcher
This object is responsible for emitting/dispatching events to the listeners.
An Emitter can:
* Add listeners to the stack
* Return listeners (all, or the ones for a specific event)
* Remove listeners
* Emit an event
## Observations
There is difference between libraries how event emitting is done. Most of them expects an array as a second parameter which contains the arguments passed to listeners. Pros: you can have your own, library based extra arguments in the emit method (like in case of sabre/event Emitter).
Most of libraries does not support using domain listeners. Since PHP 5.4 it is possible to typehint callables. Two possible solutions to support both callable and domain listeners:
1. Have an `addListener` and an `addCallableListener` method in the Emmitter. (The latter could possibly encapsulate the callable in a general CallableListener implementation.) However this forces library maintainers to support both. (Which is bad?)
2. Remove the listener part from the Emitter and move it into two interfaces: DomainListenerAware and CallableListenerAware. This way emitters can be checked if they support one or both. In this case, `addListener` could still be ambigous hence both interface can be implemented, so the naming above should still be used.
Return value of emitter: this is arguable. Probably a logical value is enough.
<?php
interface Emitter
{
/**
* Emits an event
*
* @param string|Event $event Can be an event name or an Event instance
* @param array $arguments With this (instead of func_get_args()) any other optional parameter can be used
*
* @return Return what??
*/
public function emit($event, array $arguments = []);
}
# Event
This object is responsible for holding any context related arguments.
For example: an order notification event holds the order object for reference in any notifications(sending the id in SMS, sending the items in email, etc)
An Event:
* has a name (can be casted to string?)
* can stop propagation to other listeners in the stack
* can check if the propagaton is stopped
<?php
interface Event
{
/**
* Returns the name of the event
*
* @return string
*/
public function getName();
/**
* Stops event propagation
*
* @return self
*/
public function stopPropagation();
/**
* Checks weather propagation was stopped
*
* @return boolean
*/
public function isPropagationStopped();
/**
* Event should be able to casted to string
*
* @return string
*/
public function __tostring();
}
# Listener
Either having it implemented as objects or simple closures listeners should NOT know about what events they listen to. (Is this true?) Listeners should be registered in the emitter for a specific event.
Also, a listener should be able to listen to multiple events. (Is this true? How should it be solved?)
@sagikazarmark
Copy link
Author

We want to avoid this:
http://php-and-symfony.matthiasnoback.nl/2014/08/symfony2-decoupling-your-event-system/

As much I like decoupling, it is better to have a common interface which is not tied to implementation.

@sagikazarmark
Copy link
Author

Libraries to involve (so far):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment