phphookevent-driven-design

Event-driven architecture and hooks in PHP


I am planning on working on a game that has a PHP back-end to communicate with the data repository. I was thinking about it and concluded that the best design paradigm to follow for our game would be event driven. I am looking to have an achievement system (similar to the badges system of this website) and basically I would like to be able to hook these "achievement checks" into a number of different events that occur in the game. ie:

When a user does action X hook Y is fired and all attached functions are called to check against an achievement requirement.

In structuring the architecture like this I will allow for new achievements to be added easily as all I will have to do is add the checking function to the proper hook and everything else will fall into place.

I'm not sure if this is a great explanation of what I intend to do, but in any case I am looking for the following:

  1. Good reference material on how to code an event-driven application
  2. Code snippet(s) showing how to put a "hook" in a function in PHP
  3. Code snippet(s) showing how to attach a function to the "hook" mentioned in point 2

I have a few ideas as to how to accomplish 2) and 3) but I was hoping that somebody well-versed in the matter could shed some light on best practices.

Thank you in advance!


Solution

  • Good reference material on how to code an event-driven application

    You can either do this with "dumb" callbacks (Demo):

    class Hooks
    {
        private $hooks;
        public function __construct()
        {
            $this->hooks = array();
        }
        public function add($name, $callback) {
            // callback parameters must be at least syntactically
            // correct when added.
            if (!is_callable($callback, true))
            {
                throw new InvalidArgumentException(sprintf('Invalid callback: %s.', print_r($callback, true)));
            }
            $this->hooks[$name][] = $callback;
        }
        public function getCallbacks($name)
        {
            return isset($this->hooks[$name]) ? $this->hooks[$name] : array();
        }
        public function fire($name)
        {
            foreach($this->getCallbacks($name) as $callback)
            {
                // prevent fatal errors, do your own warning or
                // exception here as you need it.
                if (!is_callable($callback))
                    continue;
    
                call_user_func($callback);
            }
        }
    }
    
    $hooks = new Hooks;
    $hooks->add('event', function() {echo 'morally disputed.';});
    $hooks->add('event', function() {echo 'explicitly called.';});
    $hooks->fire('event');
    

    Or implementing a pattern often used in event-driven applications: Observer Pattern.

    Code snippet(s) showing how to put a "hook" in a function in PHP

    The manual link above (callbacks can be stored into a variable) and some PHP code examples for the Observer Pattern.