goliatone/gdispatcher

PHP EventDispatcher。

dev-master / 1.0.x-dev 2013-10-05 20:20 UTC

This package is not auto-updated.

Last update: 2024-09-23 15:56:22 UTC


README

用户 YAML 错误:(<unknown>): 在第 2 行第 1 列扫描简单键时找不到预期的 ':'
---
TODO:
Rewrite, this is legacy!!
---

分发器

分发器模块允许实现事件驱动的应用程序流程。它具有简单的 API 和轻量级的实现,但还具有如监听器优先级或阻止事件传播的机制等特性。

使用方法简单。在引导文件中启用模块即可。没有配置选项。

一个简单的用例。在您的应用程序中,准备一个 $body 变量并发送一个事件

$event = new Event('render_body', array($this,"handle_render_body"));
$event->bind("body",$body);
$event->dispatch();

然后,在相同上下文中,定义一个处理程序方法,例如

public function handle_render_body(Event $e)
{
    $e->body .= "<p>Added in the event handler</p>;"
}

##分发器

Dispatcher 类是分发事件的基类。它通过 Dispatcher ::instance() 方法提供全局分发器。

要获取一个私有通道 - 新实例 - 我们可以使用 Dispatcher::factory(),这是 Kohana 的标准样式。

##事件

Event 类用于创建事件对象的基础类,这些对象在触发事件时作为参数传递给事件处理器。

事件的属性携带有关事件的基本信息。

事件可以携带应用程序中的信息和状态。我们可以绑定 - &referenced - 变量,以便在事件的整个生命周期中修改它们。

如果分发器允许,我们还可以通过事件的 $stop_propagation 属性从事件处理器 监听器 阻止事件传播。

//We need to specifically allow stop propagation.
$allow_stop_propagation = TRUE;
$dispatcher->dispatch_event($event, $allow_stop_propagation);
static public function event_handler(Event $e)
{
    //...modify event's payload.
    $e->stop_propagation = TRUE;
}

分发器采用保守的方法,默认将 $allow_stop_propagation 设置为 FALSE

###有效载荷

通过我们的事件,我们可以发送信息有效载荷。有两种不同的方法 setbind,类似于 Kohana 的 View 类。

虽然 bind 会通过引用分配值,但 set 会通过名称分配。稍后,在处理程序方法中,它们可以作为事件属性访问。

通过事件构造函数方法添加的任何变量都将被 set

$event = new Event('event_type',array("foo" => "foo value","bar" => "bar value"));
$event->bind($fuz,"fuz value");

static public function event_handler(Event $e)
{
    echo $e->foo; // "foo value"
    echo $e->bar; // "bar value"
    echo $e->fuz; // "fuz value"
}

从事件分发

有一个方便的方法 dispatch 用于从事件实例触发事件。如果我们打算使用私有分发器,我们应该将方法传递给它。

$event = new Event('event_type',$arguments);
//if $dispatcher is null, we use global channel.
$event->dispatch($allow_stop_propagation,$dispatcher);

##监听器

监听器通过特定事件类型的 分发器 实例注册,并在事件被触发时处理事件。它们需要接受一个类型为 Event 的参数。

Dispatcher::instance->add_listener($type,$listener, $priority);

内部,分发器将使用 call_user_func 处理监听器,因此提供的监听器最终需要转换为有效的 回调

创建有效 回调 的常规语法可以是以下任何一种

$type = "event_type";
$handler = new Event_Handler();
$dispatcher = Dispatcher::instance();

$dispatcher->add_listener($type,array($handler, "handler_method"));

$dispatcher->add_listener($type,array('Event_Handler', "static_method"));

class Event_Handler
{
    public function handler_method(Event $e)
    {
        ...
    }
    
    static function static_method(Event $e)
    {
        ...
    }
}

该方法还有一些语法上的

优先级

add_listener 的第三个参数指定回调将执行的顺序。默认值为 0。我们可以传递任何整数值 - 也可以是负值。队列将根据优先级值排序,负值是最后的。

如果我们没有指定优先级值,则监听器将以添加的顺序调用。

$dispatcher->add_listener('some_event_type',$handler1);
$dispatcher->add_listener('some_event_type',$handler2);
$dispatcher->add_listener('some_event_type',$handler3);

//Order:
//$handler1::some_event_type($e)
//$handler2::some_event_type($e)
//$handler3::some_event_type($e)

$dispatcher->add_listener('some_event_type',$handler1,-2);
$dispatcher->add_listener('some_event_type',$handler2);
$dispatcher->add_listener('some_event_type',$handler3,10);

//Order:
//$handler3::some_event_type($e)
//$handler2::some_event_type($e)
//$handler1::some_event_type($e)

如果我们有一个匹配事件类型的函数,我们直接传递一个实例。这样我们就不再需要数组了。

$dispatcher->add_listener('some_event_type',$handler);
$dispatcher->add_listener('static_event_type','Event_Handler');


class Event_Handler
{
    public function some_event_type(Event $e)
    {
        ...
    }
    
    static public static_event_type(Event $e)
    {
        ...
    }        
}

我们还可以通过提供一个字符串来为静态方法提供一个快捷方式。

$dispatcher->add_listener('event_type','Event_Handler::static_handler');

class Event_Handler
{
    static public static_handler(Event $e)
    {
        ...
    }        
}