PHP:如何实现事件处理程序?

6
我希望为对象的方法添加自定义事件处理程序。
我有一个带有方法的类。
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

使用这里定义的函数应该很容易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"即可(如果需要多个处理程序,则可能需要在循环中调用)。


如何从我的“添加”方法调用处理程序? - foreline

1

如果你使用的是 < php 5.3 版本,那么你不能以这种方式创建闭包,但你可以通过 create_function() 来接近实现;

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

然后你将$handler存储在类中,可以根据需要调用它。


1

方法

ircmaxell在这里描述了多种实现它的方法。

这里是ToroPHP(路由库)中使用的ToroHook。

钩子

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

请看我的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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接