Events

PHP does not provide events as a first class language feature. However using closures we can achieve much the same thing.

Rhubarb provides two strategies for implementing event handling: the EventEmitter trait and the Event object.

EventEmitter

The EventEmitter which you can use in any class to add event dispatching support to any existing object.

Dispatching Events

Firstly use the trait on your class:

class MyClass
{
use EventEmitter;
}

Now to raise an event simply call the raiseEvent function. Pass any arguments you wish to the listeners. For
example here we raise an event called SomethingInterestingHappened and pass two arguments to any listener.

Listening to events

Simply call the public attachEventHandler() method of the object that raises events and pass the name of the
event to listen to and an anonymous function to be used as a callback. The callback can define arguments that
will receive the values passed when the event was raised.

Sometimes you need to allow all listeners to return a value. This is achieved by passing another closure
as the last argument when calling raiseEvent. If passed this closure will be called with the return
value from each listener:

Using constants for event names

As event names are strings it is quite common to find an event handler isn't firing because of a simple misspelling
or perhaps someone has renamed the emitted event. A good practice is to use constants instead of string literals
to make sure the IDE can assist you in getting the right event name. The constant should be defined in the
emitting class:

The Event object

One down side of the EventEmitter is that event names are simple strings often leading to simple errors where
events aren't hooked up properly because of misspellings or refactoring excercises gone wrong. This can be
mitigated to some degree by using constants for event names but a developer still can't easily see what events
are emitted by your object.

A more formal approach to events uses the Event object.

Define the event property

For each event you plan to raise you should add a public named property and initialise this to an instance
of 'Event':

Arguments, return values and response call backs.

These operate in exactly the same way as for the EventEmitter. You can pass any number of arguments,
receive a return value (first handler to do so) and pass a callback function as the final argument which
is passed to handlers so that all handlers can return value.s