https://github.com/kuria/event
Event library that implements variations of the mediator and observer patterns
https://github.com/kuria/event
emitter event-dispatcher event-emitter listeners observable observer php subscribers
Last synced: about 1 year ago
JSON representation
Event library that implements variations of the mediator and observer patterns
- Host: GitHub
- URL: https://github.com/kuria/event
- Owner: kuria
- License: mit
- Created: 2014-06-22T16:29:29.000Z (almost 12 years ago)
- Default Branch: master
- Last Pushed: 2023-04-22T14:38:43.000Z (about 3 years ago)
- Last Synced: 2025-04-14T23:13:26.892Z (about 1 year ago)
- Topics: emitter, event-dispatcher, event-emitter, listeners, observable, observer, php, subscribers
- Language: PHP
- Homepage:
- Size: 59.6 KB
- Stars: 5
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.rst
- Changelog: CHANGELOG.rst
- License: LICENSE
Awesome Lists containing this project
README
Event
#####
Event library that implements variations of the mediator and observer patterns.
.. image:: https://travis-ci.com/kuria/event.svg?branch=master
:target: https://travis-ci.com/kuria/event
.. contents::
:depth: 2
Features
********
- emitting events with any number of arguments
- managing listeners for specific or all events
- ordering listeners by priority
- stopping event propagation
- multiple ways to embed the event system
Requirements
************
- PHP 7.1+
Components
**********
Event emitter
=============
The ``EventEmitter`` class maintains a list of listeners and dispatches events
to them.
It is intended to be used as a mediator.
.. code:: php
emit('something');
}
}
Alternatively, you can use the ``ObservableTrait`` to achieve the same result:
.. code:: php
on('some.event', function ($arg1, $arg2) {
// do something
});
- the callback can stop event propagation by returning ``FALSE``
- `listener priority`_ can be specified using the 3rd argument of ``on()``
To unregister a callback, call the ``off()`` method with the same callback
(in case of closures this means the same object):
.. code:: php
off('some.event', $callback); // returns TRUE on success
Using an event listener
-----------------------
To register an event listener, use the ``addListener()`` method:
.. code:: php
addListener(
new EventListener(
'some.event',
function ($arg1, $arg2) {}
)
);
- `listener priority`_ can be specified by using the 3rd argument of
the ``EventListener`` constructor
- the callback can stop event propagation by returning ``FALSE``
To unregister a listener, call the ``removeListener()`` method with the same
event listener object:
.. code:: php
removeListener($eventListener); // returns TRUE on success
Using an event subscriber
-------------------------
Event subscribers subscribe to a list of events. Each event is usually mapped
to one method of the subscriber.
The listeners can be created using the convenient ``listen()`` method
(as shown in the example below) or by manually creating ``EventListener``
instances.
- any callback or method can stop event propagation by returning ``FALSE``
- `listener priority`_ can be specified using 3rd argument of ``listen()``
or the ``EventListener`` constructor
.. code:: php
listen('foo.bar', 'onFooBar'),
$this->listen('lorem.ipsum', 'onLoremIpsum', 10),
$this->listen('dolor.sit', 'onDolorSitA'),
$this->listen('dolor.sit', 'onDolorSitB', 5),
];
}
function onFooBar() { /* do something */ }
function onLoremIpsum() { /* do something */ }
function onDolorSitA() { /* do something */ }
function onDolorSitB() { /* do something */ }
}
$subscriber = new MySubscriber();
Registering the event subscriber:
.. code:: php
subscribeTo($observable);
Unregistering the event subsriber:
.. code:: php
unsubscribeFrom($observable);
Stopping event propagation
--------------------------
Any listener can stop further propagation of the current event by returning ``FALSE``.
This prevents any other listeners from being invoked.
Listener priority
-----------------
Listener priority determines the order in which the listeners are invoked:
- listeners with greater priority are invoked sooner
- listeners with lesser priority are invoked later
- if the priorities are equal, the order of invocation is undefined
- priority can be negative
- default priority is ``0``
Listening to all events
=======================
To listen to all events, use ``ObservableInterface::ANY_EVENT`` in place
of the event name:
.. code:: php
on(
ObservableInterface::ANY_EVENT,
function ($event, $arg1, $arg2) {}
);
$observable->addListener(
new EventListener(
ObservableInterface::ANY_EVENT,
function ($event, $arg1, $arg2) {}
)
);
- global listeners are invoked before listeners of specific events
- global listeners get an extra event name argument before the emitted
event arguments
- global listeners can also stop event propagation by returning ``FALSE``
and may have specified `listener priority`_
Emitting events
===============
Events are emitted using the ``emit()`` method.
.. code:: php
emit('foo');
Any extra arguments will be passed to the listeners.
.. code:: php
emit('foo', 'hello', 123);
.. NOTE::
Variable references cannot be emitted directly as an argument. If you need to use
references, wrap them in an object or an array.
Documenting events
==================
While the event library itself doesn't require this, it is a good idea to explicitly define
possible event names and their arguments somewhere.
The example below defines a ``FieldEvents`` class for this purpose. Constants of this class
are then used in place of event names and their annotations serve as documentation. This also
allows for code-completion.
.. code:: php
name = $name;
$this->value = $value;
}
function getName(): string
{
return $this->name;
}
function getValue()
{
return $this->value;
}
function setValue($value): void
{
$this->emit(FieldEvents::CHANGE, $this, $this->value, $value);
$this->value = $value;
}
function clear()
{
$this->emit(FieldEvents::CLEAR, $this);
$this->value = null;
}
}
.. NOTE::
Using ``@param`` annotations on class constants is non-standard, but IDE's dont mind
it and some documentation-generators (such as Doxygen) even display them nicely.
Usage example
-------------
.. code:: php
on(FieldEvents::CHANGE, function (Field $field, $oldValue, $newValue) {
echo "Field '{$field->getName()}' has been changed from '{$oldValue}' to '{$newValue}'\n";
});
$field->on(FieldEvents::CLEAR, function (Field $field) {
echo "Field '{$field->getName()}' has been cleared\n";
});
$field->setValue('john.smith');
$field->setValue('foo.bar123');
$field->clear();
Output:
::
Field 'username' has been changed from '' to 'john.smith'
Field 'username' has been changed from 'john.smith' to 'foo.bar123'
Field 'username' has been cleared