Событийная архитектура и хуки в PHP - PullRequest
12 голосов
/ 27 июля 2011

Я планирую работать над игрой, которая имеет PHP-интерфейс для взаимодействия с хранилищем данных. Я подумал об этом и пришел к выводу, что лучшая парадигма дизайна для нашей игры будет основана на событиях. Мне нужна система достижений (похожая на систему значков на этом сайте), и в основном я бы хотел подключить эти «проверки достижений» к ряду различных событий, происходящих в игре. то есть:

Когда пользователь выполняет действие X, ловушка Y запускается, и все присоединенные функции вызываются для проверки соответствия требованию достижения.

При структурировании архитектуры, подобной этой, я позволю легко добавлять новые достижения, так как все, что мне нужно будет сделать, это добавить функцию проверки в соответствующий хук, и все остальное станет на свои места.

Я не уверен, что это отличное объяснение того, что я собираюсь сделать, но в любом случае я ищу следующее:

  1. Хороший справочный материал о том, как кодировать приложение, управляемое событиями
  2. Фрагменты кода, показывающие, как поместить «зацепку» в функцию в PHP
  3. Фрагменты кода, показывающие, как прикрепить функцию к «крючку», указанному в пункте 2

У меня есть несколько идей относительно того, как выполнить 2) и 3), но я надеялся, что кто-то хорошо разбирающийся в этом вопросе сможет пролить свет на лучшие практики.

Заранее спасибо!

Ответы [ 3 ]

14 голосов
/ 27 июля 2011

Хороший справочный материал о том, как кодировать приложение, управляемое событиями

Вы можете сделать это с помощью "немых" обратных вызовов ( 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');

Или реализация шаблона, часто используемого в управляемых событиями приложениях: Шаблон наблюдателя .

Фрагменты кода, показывающие, как поместить «зацепку» в функцию в PHP

Указанная выше ручная ссылка (обратные вызовы могут быть сохранены в переменную) и некоторые примеры кода PHP для шаблона Observer .

5 голосов
/ 27 июля 2011

Для PHP я регулярно интегрировал компонент Symfony Event: http://components.symfony -project.org / event-dispatcher / .

Ниже приведен краткий пример, который вы можете найтирасширен в разделе Рецепт Symfony .

<?php

class Foo
{
  protected $dispatcher = null;

    // Inject the dispatcher via the constructor
  public function __construct(sfEventDispatcher $dispatcher)
  {
    $this->dispatcher = $dispatcher;
  }

  public function sendEvent($foo, $bar)
  {
    // Send an event
    $event = new sfEvent($this, 'foo.eventName', array('foo' => $foo, 'bar' => $bar));
    $this->dispatcher->notify($event);
  }
}


class Bar
{
  public function addBarMethodToFoo(sfEvent $event)
  {
    // respond to event here.
  }
}


// Somewhere, wire up the Foo event to the Bar listener
$dispatcher->connect('foo.eventName', array($bar, 'addBarMethodToFoo'));

?>

Это система, которую мы интегрировали в корзину для покупок, чтобы создать подобный игре опыт, привязывая действия пользователя к игровым событиям.Когда пользователь выполнял определенные действия, php запускал события, вызывая срабатывание вознаграждений.

Пример 1: если пользователь нажал определенную кнопку 10 раз, он получил звездочку.

Пример 2: когда пользователь ссылается на друга и этот друг регистрируется, происходит событие, награждающее исходного реферера баллами.

1 голос
/ 27 июля 2011

Проверьте CodeIgniter , поскольку он имеет крючки, встроенные прямо в .

Просто включите крючки:

$config['enable_hooks'] = TRUE;

И затем определите свой крючок:

 $hook['post_controller_constructor'] = array(
                                'class'    => 'Hooks',
                                'function' => 'session_check',
                                'filename' => 'hooks.php',
                                'filepath' => 'hooks',
                                'params'   => array()
                                ); 

Тогда используйте его в своем классе:

<?php

    class Hooks {
        var $CI;

        function Hooks() {
            $this->CI =& get_instance();
        }

        function session_check() {
            if(!$this->CI->session->userdata("logged_in") && $this->CI->uri->uri_string != "/user/login")
                redirect('user/login', 'location');
        }
    }

?> 
...