Spiffy\Dispatch can be installed using composer which will setup any autoloading for you.
composer require spiffy/spiffy-dispatch
Additionally, you can download or clone the repository and setup your own autoloading.
Dispatching can be done via the Dispatchable
interface, a Closure
, callable
, or invokable
.
The Dispatchable
interface has a single dispatch
method that accepts an array of parameters. There is no
reflection involved in dispatching this way so it is the most performant.
use Spiffy\Dispatch\Dispatcher;
class TestDispatchable implements Dispatchable
{
public function dispatch(array $params) { return 'foo'; }
}
$d = new Dispatcher();
$d->add('foo', new TestDispatchable());
// outputs 'foo'
echo $d->ispatch('foo');
// the second argument will be passed to the $params array of the dispatch() method
echo $d->ispatch('foo', ['name' => 'bar']);
Dispatching via a closure is useful for micro-frameworks or for quickly setting up prototypes.
use Spiffy\Dispatch\Dispatcher();
$d = new Dispatcher();
$d->add('foo', function() { return 'foo'; });
// outputs 'foo'
echo $d->ispatch('foo');
// this closure has a default value of 'baz' for the $slug parameter
$d->add('bar', function($id, $slug = 'baz') {
return $id . ': ' . $slug;
)};
// this uses the default value for $slug
// outputs '1: baz'
echo $d->ispatch('bar', ['id' => 1]);
// this overwrites the default value
// outputs '1: booze'
echo $d->ispatch('bar', ['id' => 1, 'slug' => 'booze']);
use Spiffy\Dispatch\Dispatcher;
class TestInvokable implements Dispatchable
{
public function __invoke($id, $slug = 'baz')
{
return $id . ': ' . $slug;
}
}
$d = new Dispatcher();
$d->add('foo', new TestInvokable());
// this uses the default value for $slug
// outputs '1: baz'
echo $d->ispatch('bar', ['id' => 1]);
// this overwrites the default value
// outputs '1: booze'
echo $d->ispatch('bar', ['id' => 1, 'slug' => 'booze']);
use Spiffy\Dispatch\Dispatcher;
class TestCallable implements Dispatchable
{
public function outputId($id)
{
return $id;
}
public static function outputStaticId($id)
{
return $id;
}
}
$test = new TestCallable();
$d = new Dispatcher();
$d->add('foo', [$test, 'outputId']);
// output is '1'
$d->ispatch('foo', ['id' => 1]);
$d->add('bar', 'TestCallable::outputStaticId');
// output is '2'
$d->ispatch('bar', ['id' => 2]);
The dispatcher will continue to dispatch as long as a dispatchable is returned. This allows you to lazy-load objects by using a closure (which is dispatchable).
<?php
use Spiffy\Dispatch\Dispatcher;
$d = new Dispatcher();
// assume the TestDispatchable class from above
// instead of this
$d->add('foo', new TestDispatchable());
// you would do this
$d->add('foo', function() {
return new TestDispatchable();
});
// the output is identical to the output from Dispatchable above
// the only difference is that it's lazy loaded on dispatch() instead.
Because it's damn cute, that's why! If you prefer, though, you can use dispatch()
instead as ispatch()
is a simple
proxy call to dispatch()
.