php event system implementation
events, php
Solution
There must be an instance of class A before the event is triggered because you must register for that event. An exception would be if you'd register a static method.
Let's say you have an User class which should trigger an event. First you need an (abstract) event dispatcher class. This kind of event system works like ActionScript3:
abstract class Dispatcher
{
protected $_listeners = array();
public function addEventListener($type, callable $listener)
{
// fill $_listeners array
$this->_listeners[$type][] = $listener;
}
public function dispatchEvent(Event $event)
{
// call all listeners and send the event to the callable's
if ($this->hasEventListener($event->getType())) {
$listeners = $this->_listeners[$event->getType()];
foreach ($listeners as $callable) {
call_user_func($callable, $event);
}
}
}
public function hasEventListener($type)
{
return (isset($this->_listeners[$type]));
}
}
Your User class can now extend that Dispatcher:
class User extends Dispatcher
{
function update()
{
// do your update logic
// trigger the event
$this->dispatchEvent(new Event('User_update'));
}
}
And how to register for that event? Say you have class A with method `update`.
// non static method
$classA = new A();
$user = new User();
$user->addEventListener('User_update', array($classA, 'update'));
// the method update is static
$user = new User();
$user->addEventListener('User_update', array('A', 'update'));
If you have proper autoloading the static method can be called. In both cases the `Event` will be send as parameter to the `update` method. If you like you can have an abstract Event class, too.
Problem
I would like to implement an Event system in my custom MVC framework, to allow decoupling of classes that need to interact with each other. Basically, the ability for any class to trigger an event and any other class that listens for this event to be able to hook into it. However, I cannot seem to find a correct implementation given the nature of php's share nothing architecture. For instance, let's say that I have a User model that each time that it is updated, it triggers a userUpdate event. Now, this event is useful for class A (for instance) as it needs to apply its own logic when a user is updated. However, class A is not loaded when a user is updated, so it cannot bind to any events triggered by the User object. How can you get around such a scenario? Am I approaching it wrongly? Any ideas would be greatly appreciated