Yii源码解读 - 事件

niecprea

Yii基础

事件 event

使用事件,可以在特定的时点,触发执行预先设定的一段代码,事件既是代码解耦的一种方式,也是设计业务流程的一种模式。

事件的相关要素

  • 这是一个什么事件?

  • 谁触发了事件?

  • 谁负责监听这个事件?

  • 事件怎么处理?

  • 事件的相关数据是什么?

事件的引入

事件是从yii\base\Component类开始出现的。与事件相关的另外一个类是yii\base\Event,他封装了一些方法,同时提供一些辅助。

事件handler

事件handler就是事件处理程序,负责事件触发后应该怎么办。handler可以是以下形式:

  • 函数名

  • 对象的方法,或类的静态方法

  • 匿名函数

一个handler必须是以下方式

function ($event){
    // $event就是yii\base\Event
}

handler的调用是通过call_user_func()来实现的。

事件的绑定和解除

yii\base\Component::on(), yii\base\Component::off()对事件进行绑定和解绑。

person = new Person;

// 使用PHP全局函数作为handler来进行绑定
$person->on(Person::EVENT_GREET, 'person_say_hello');

// 使用对象$obj的成员函数say_hello来进行绑定
$person->on(Person::EVENT_GREET, [$obj, 'say_hello']);

// 使用类Greet的静态成员函数say_hello进行绑定
$person->on(Person::EVENT_GREET, ['app\helper\Greet', 'say_hello']);

// 使用匿名函数
$person->on(Person::EVENT_GREET, function ($event) {
    echo 'Hello';
});
private _events = [];

上面的数组是用来维护事件handler数组。该数组的下标为事件名,数组元素是形为一系列 [$handler, $data] 的数组

handler$event[]数组中的位置很重要,代表的是执行的先后顺序。执行的先后顺序很重要。

在解除事件时,可以把一个事件下的所有handler都解除掉。

事件的触发

事件的触发,需要调用yii\base\Component::trigger()

yii\base\Application->run(),很好的举例说明了触发器如何调用。

使用 yii\base\Component::on() 可以为各种事件绑定handler,也可以为同一事件绑定多个handler。
triggeron传入数据方法不同。在on()中,使用一个简单变量,传入,并在handler中通过$event->data进行访问。这个是在绑定时确定的数据。而有的数据是没办法在绑定时确定的。

事件的级别

类级别事件

类级别事件用于响应所有类实例的事件。

类级别事件的绑定需要使用yii\base\Event::on()

类级别事件的触发仍然是在yii\base\Component::trigger()

类级别事件的触发,应使用yii\base\Event::trigger()。这个函数不会触发实例级别的事件。

全局事件

利用了Application实例在整个应用的生命周期中全局可访问的特性,来实现这个全局事件的。当然,你也可以将他绑定在任意全局可访问的的Component上。

全局事件一个最大优势在于:在任意需要的时候,都可以触发全局事件,也可以在任意必要的时候绑定,或解除一个事件:

Yii::$app->on('bar', function ($event) {
    echo get_class($event->sender);
});

Yii::$app->trigger('bar', new Event(['sender' => $this]));

上面的Yii::$app->on()可以在任何地方调用,就可以完成事件的绑定。而 Yii::$app->trigger()只要在绑定之后的任何时候调用就OK了。

参考

  1. http://www.digpage.com

阅读 1.4k

ThinkingPool
Y1RReE5qazFOVFl5

Hello world!

859 声望
54 粉丝
0 条评论
你知道吗?

Hello world!

859 声望
54 粉丝
宣传栏