Events and observers

Event dispatching systems and Observer Design pattern are often used to implement distributed event handling systems. They are also key parts in the model–view–controller (MVC) architectural pattern.

EventDispatcing system:

The SPHP EventDispatcing system consists of three different type of objects.

  1. an object implementing EventDispatcherInterface
  2. a number of EventListener objects attached to it
  3. Event objects dispatched by the dispatcher to its listener objects

The Event in details

DataEvent class is a build-in instantiable implementation of the Event. An DataEvent is identified by a inmutable unique name, which any number of EventListener might be listening to. An Event instance is passed to all of the listeners. The Event object itself often contains data about the event being dispatched.

Event Naming Conventions

The unique event name can be any string, but optionally follows a few simple naming conventions:

  • only lowercase letters, numbers, dots (.), and underscores (_);
  • prefix names with a namespace followed by a dot (e.g. kernel.);
  • end names with a verb that indicates what action is being taken (e.g. request).

Here are some examples of good event names:

html.attributes.id.change html.attributes.id.change

  • PHP code
    1. <?php
    2.  
    3. namespace Sphp\Stdlib\Events;
    4.  
    5. class OwnListener implements EventListener {
    6.  
    7.   public function on(Event $event) {
    8.     echo "\n" . Listener::class . " got an event:\n";
    9.     var_dump($event->getData());
    10.   }
    11.  
    12. }
    13.  
    14. $fun = function(Event $event) {
    15.   echo "\nClosure fun got an event:\n";
    16.   var_dump($event->getData());
    17. };
    18.  
    19. $manager = new EventDispatcher();
    20. $manager->addListener("e1", $l = new OwnListener);
    21. $manager->addListener("e1", $fun);
    22. $manager->addListener("e2", $fun);
    23. $manager->trigger(new DataEvent("e1", $manager, "Hello e1 listeners"));
    24. $manager->trigger(new DataEvent("e2", $manager, "Hello e12 listeners"));
    25.  
    Highlighted with GeSHi 1.0.9.1
  • Execution result as highlighted code
    1.  
    2. Sphp\Stdlib\Events\Listener got an event:
    3. string(18) "Hello e1 listeners"
    4.  
    5. Closure fun got an event:
    6. string(18) "Hello e1 listeners"
    7.  
    8. Closure fun got an event:
    9. string(19) "Hello e12 listeners"
    10.  
    Highlighted with GeSHi 1.0.9.1

Observer Design Pattern and The SubjectTrait

Observer pattern is used when there is one-to-many relationship between objects such as if one object is modified, its depenedent objects are to be notified automatically. Observer pattern is a behavioral pattern.

Interfaces Observer and Subject can be used implement the Observer Design Pattern. The subject can take any callable type or an Observer object as its observer. The SubjectTrait is a trait implementation of Subject interface.

  • PHP code
    1. <?php
    2.  
    3. namespace Sphp\Stdlib\Observers;
    4.  
    5. class Subject1 implements Subject {
    6.  
    7.   use SubjectTrait;
    8.  
    9.   public $message;
    10.  
    11.   public function say($message) {
    12.     $this->message = $message;
    13.     $this->notify();
    14.   }
    15.  
    16. }
    17.  
    18. class Observer1 implements Observer {
    19.  
    20.   public function update(Subject $subject) {
    21.     echo "Observer1: $subject->message\n";
    22.   }
    23.  
    24. }
    25.  
    26. $observer2 = function(Subject $subject) {
    27.   echo "A function can also hear me: $subject->message\n";
    28. };
    29.  
    30. $subject = new Subject1();
    31. $subject->attach(new Observer1);
    32. $subject->attach($observer2);
    33. $subject->say("hello");
    34. $subject->say("hello again");
    35.  
    Highlighted with GeSHi 1.0.9.1
  • Execution result as highlighted code
    1. Observer1: hello
    2. A function can also hear me: hello
    3. Observer1: hello again
    4. A function can also hear me: hello again
    5.  
    Highlighted with GeSHi 1.0.9.1