PHP: Как реализовать обработчик событий? - PullRequest
6 голосов
/ 09 октября 2010

Я хочу добавить пользовательский обработчик событий в метод объекта.

У меня есть класс с методом.

class Post {

    public function Add($title) {

        // beforeAdd event should be called here

        echo 'Post "' . $title . '" added.';
        return;
    }
}

Я хочу добавить событие в метод Add и передать аргументы метода в обработчик события.

function AddEventHandler($event, $handler){
    // What should this function do?
}

$handler = function($title){
    return strtoupper($title);
}

AddEventHandler('beforeAdd', $handler);

Можно ли сделать что-то подобное? Надеюсь, мой вопрос ясен.

Ответы [ 4 ]

4 голосов
/ 09 октября 2010

Должно быть довольно просто использовать функции, определенные здесь http://www.php.net/manual/en/book.funchand.php

В частности, вы должны сохранить массив обработчиков (или массив массивов, если вам нужно несколько обработчиков для одного и того же события), а затем просто сделать что-то вроде

function AddEventHandler($event, $handler){
    $handlerArray[$event] = $handler;
}

или

function AddEventHandler($event, $handler){
    $handlerArray[$event][] = $handler;
}

в случае нескольких обработчиков.

В этом случае вызов обработчиков будет просто вопросом вызова " call_user_func "(в конечном итоге в цикле, если требуется несколько обработчиков)

1 голос
/ 19 мая 2015

Взгляните на мою sphido / events библиотека:

  • это просто в использовании (несколько строк кода)
  • на основе Обработка функций PHP
  • разрешить приоритезацию слушателей
  • добавить / удалить слушателей
  • фильтрация значений по функциям
  • остановить распространение в функциональной цепочке
  • добавить обработчик по умолчанию

Пример обработчика событий

on('event', function () {
  echo "wow it's works yeah!";
});

fire('event'); // print wow it's works yeah!

Пример функции фильтра

add_filter('price', function($price) {
  return (int)$price . ' USD';
});

echo filter('price', 100); // print 100 USD
1 голос
/ 08 сентября 2014

Методы

У вас есть несколько способов, как это сделать, описанные ircmaxell здесь .

А вот ToroHook, используемый в ToroPHP (Routing lib).

Крючок

class ToroHook {
    private static $instance;
    private $hooks = array();

    private function __construct() {}
    private function __clone() {}

    public static function add($hook_name, $fn){
        $instance = self::get_instance();
        $instance->hooks[$hook_name][] = $fn;
    }

    public static function fire($hook_name, $params = null){
        $instance = self::get_instance();
        if (isset($instance->hooks[$hook_name])) {
            foreach ($instance->hooks[$hook_name] as $fn) {
                call_user_func_array($fn, array(&$params));
            }
        }
    }
    public static function remove($hook_name){
        $instance = self::get_instance();
        unset($instance->hooks[$hook_name]);
        var_dump($instance->hooks);
    }
    public static function get_instance(){
        if (empty(self::$instance)) {
            self::$instance = new Hook();
        }
        return self::$instance;
    }
}

Использование крючка

Это просто назвать так:

ToroHook::add('404', function($errorpage){
    render("page/not_found", array("errorpage" => $errorpage));
});
1 голос
/ 09 октября 2010

Что ж, если вы используете

$handler = create_function('$title', 'return strtoupper($title);');

Затем вы храните обработчик $ в классе и можете вызывать его по своему желанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...