Skip to content

Instantly share code, notes, and snippets.

@Ocramius
Last active January 10, 2023 16:34
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save Ocramius/7436435 to your computer and use it in GitHub Desktop.
Save Ocramius/7436435 to your computer and use it in GitHub Desktop.
`Zend\EventManager` examples
vendor
composer.lock
<?php
use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareTrait;
use Zend\EventManager\EventManagerInterface;
require_once __DIR__ . '/vendor/autoload.php';
// Abstract aggregate listeners are a formalized way of writing a listener in a (testable) class
class MyListener extends AbstractListenerAggregate
{
public function attach(EventManagerInterface $events)
{
$this->listeners[] = $events->attach('foo', [$this, 'onFoo']);
$this->listeners[] = $events->attach('bar', [$this, 'onBar']);
}
public function onFoo()
{
echo "Foo!\n";
}
public function onBar()
{
echo "Bar!\n";
}
}
$evm = new EventManager();
$evm->attach(new MyListener());
$evm->trigger('bar');
$evm->trigger('foo');
$evm->trigger('foo');
<?php
namespace CatchAll;
use Zend\EventManager\EventInterface;
use Zend\EventManager\EventManagerAwareTrait;
use Zend\ModuleManager\Feature\InitProviderInterface;
use Zend\ModuleManager\ModuleManagerInterface;
require_once __DIR__ . '/vendor/autoload.php';
/** A module class that tracks all events being triggered in an application */
class Module implements InitProviderInterface
{
/** {@inheritDoc} */
public function init(ModuleManagerInterface $manager)
{
$manager->getEventManager()->getSharedManager()->attach(
'*',
'*',
function (EventInterface $event) {
$target = $event->getTarget();
$targetName = is_object($target) ? get_class($target) : gettype($target);
echo 'Triggered "' . $event->getName() . '" on "' . $targetName . "\"\n";
},
100000
);
}
}
<?php
use Zend\EventManager\Event;
use Zend\EventManager\EventInterface;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerAwareTrait;
require_once __DIR__ . '/vendor/autoload.php';
// This is a variation of `pre-and-post-triggers.php` implemented as a chain
// of responsibility via listener priorities
class MyService implements EventManagerAwareInterface
{
use EventManagerAwareTrait;
public function __construct()
{
// the actual logic is a listener
$this->getEventManager()->attach('veryVerySlow', function (EventInterface $e) {
sleep(2); // very slow on purpose!
$e->setParam('result', rand(1, 99999));
});
}
public function veryVerySlow()
{
$event = new Event('veryVerySlow');
$this->getEventManager()->trigger($event);
return $event->getParam('result');
}
}
class Cache {
private $item;
public function isEmpty()
{
return ! $this->item;
}
public function gimme()
{
return $this->item;
}
public function write($item)
{
$this->item = $item;
}
}
$cache = new Cache();
$service = new MyService();
$service->getEventManager()->attach('veryVerySlow', function (EventInterface $e) use ($cache) {
echo "Checking cache\n";
if (! $cache->isEmpty()) {
echo "Cache Hit\n";
$e->stopPropagation(true);
$e->setParam('result', $cache->gimme());
}
});
$service->getEventManager()->attach('veryVerySlow', function (EventInterface $e) use ($cache) {
echo "Writing to cache\n";
$cache->write($e->getParam('result'));
});
echo "Result:" . $service->veryVerySlow() . "\n";
echo "Result:" . $service->veryVerySlow() . "\n";
echo "Result:" . $service->veryVerySlow() . "\n";
{
"require": {
"php": ">=5.4",
"zendframework/zend-eventmanager": "2.2.*"
}
}
<?php
use Zend\EventManager\EventInterface;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerAwareTrait;
require_once __DIR__ . '/vendor/autoload.php';
// in this example, we are caching the result of some logic without introducing
// a dependency to the cache in MyService
class MyService implements EventManagerAwareInterface
{
use EventManagerAwareTrait;
public function veryVerySlow()
{
$result = $this->getEventManager()->trigger('veryVerySlow.pre', $this, []);
if ($result->last()) {
return $result->last();
}
$result = rand(1, 99999);
sleep(2); // very slow on purpose!
$this->getEventManager()->trigger('veryVerySlow.post', $this, ['result' => $result]);
return $result;
}
}
class Cache {
private $item;
public function isEmpty()
{
return ! $this->item;
}
public function gimme()
{
return $this->item;
}
public function write($item)
{
$this->item = $item;
}
}
$cache = new Cache();
$service = new MyService();
$service->getEventManager()->attach('veryVerySlow.pre', function () use ($cache) {
echo "Checking cache\n";
if (! $cache->isEmpty()) {
echo "Cache Hit\n";
return $cache->gimme();
}
});
$service->getEventManager()->attach('veryVerySlow.post', function (EventInterface $e) use ($cache) {
echo "Writing to cache\n";
$cache->write($e->getParam('result'));
});
echo "Result:" . $service->veryVerySlow() . "\n";
echo "Result:" . $service->veryVerySlow() . "\n";
echo "Result:" . $service->veryVerySlow() . "\n";
<?php
use Zend\EventManager\EventInterface;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerAwareTrait;
use Zend\EventManager\SharedEventManager;
require_once __DIR__ . '/vendor/autoload.php';
// This example shows how to use the shared event manager to listen to events
// on objects that are not yet instantiated
// That allows decoupling service definitions for listeners and services
class UserService implements EventManagerAwareInterface
{
use EventManagerAwareTrait;
public function login($user)
{
$this->getEventManager()->trigger('user_login', $this, ['user' => $user]);
}
}
$shEvm = new SharedEventManager();
$shEvm->attach(
'UserService',
'user_login',
function (EventInterface $e) {
echo 'Login: ' . $e->getParam('user') . "\n";
}
);
// later, in program execution:
$userService = new UserService();
// note: this injection is usually handled in the service manager
$userService->getEventManager()->setSharedManager($shEvm);
$userService->login('Ocramius');
$otherService = new UserService();
$otherService->getEventManager()->setSharedManager($shEvm);
$otherService->login('Mr. Bean');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment