概念理解分析:当某个事件(trigger)发生时,触发预设的(on)代码,是一种代码解耦的方式。事件根据级别分为三类。1.在实例级别绑定事件,触发事件的类继承自Component,Component只运行在当前实例中,与该类的其他实例没有关系,与其他类或其他实例也没有关系。.代码示例:data;$事件->处理=真;}publicfunctionsayWorld($event){echo$event->data;}}1。绑定事件:$event=newEventTest();$event->on(EventTest::EVENT_SAY_HELLO,[$event,'sayHello'],'Hello!');$event->on(EventTest::EVENT_SAY_HELLO,[$事件,“说世界”],“世界!”);2.取消事件:$event->off(EventTest::EVENT_SAY_HELLO,[$event,'sayHello']);3.触发事件:$event->trigger(EventTest::EVENT_SAY_HELLO);2.类级绑定事件,触发事件的类继承自Event,类级事件会被类自身、类实例、子类、子类实例的同一个事件触发,范围影响较大代码示例:data;}公共函数sayWorld($event){回声$事件->数据;}}1.绑定事件:$event=newEventTest();$event->on('\common\components\EventTest',EventTest::EVENT_SAY_HELLO,[$event,'sayHello'],'Hello!');$event->on('\common\components\EventTest',EventTest::EVENT_SAY_HELLO,[$event,'sayWorld'],'World!');2.取消事件:$event->off('\common\components\EventTest',EventTest::EVENT_SAY_HELLO,[$event,'sayWorld']);3、触发事件:$event->trigger('\common\components\EventTest',EventTest::EVENT_SAY_HELLO);类级别比实例级别多了一个参数:类名注意:如果不传递句柄取消事件,则该事件下的所有句柄都会被释放。将$event->handled=true添加到其中一个句柄也将防止触发后续句柄,如上面的代码。3、全局层面利用Application实例在整个应用生命周期中全局可访问的特性来实现这个全局事件。可以在需要时触发全局事件,也可以在需要时绑定或撤消事件。代码示例:1.绑定事件:$event=newEventTest();Yii::$app->on('global_event',[$event,'globalEvent'],'globalevent');2.触发事件:Yii::$app->trigger('global_event');全球层面其实也是一个特例。[注意,所谓全局作用域只在当前请求的生命周期内有效,而不是当前会话(简单地说,打开浏览器,访问服务器,直到浏览器关闭,才称为一个会话)】原理实例级维护了Component类的属性$_events是一个数组。当触发事件时,通过[事件名称]获取[当前实例]的句柄数据,然后通过函数call_user_func触发句柄。在类层面,通过维护Event类的属性$_events数组,当事件触发时,通过[类名和事件名]获取[当前类和父类]的句柄数据,然后该句柄通过函数call_user_func触发。Component的$_event数据结构示例如下Array([say_hello]=>Array([0]=>Array([0]=>Array([0]=>common\components\EventTestObject([_events:yii\base\Component:private]=>Array*RECURSION*[_eventWildcards:yii\base\Component:private]=>Array()[_behaviors:yii\base\Component:private]=>Array())[1]=>say_hello)[1]=>Hello!)))总结以上总结是对Yii2.0的深入理解。其实以前也见过,只是见过而已。明白了,其实过两天什么都不记得了,所以现在想通过写博客来加深理解。其实这篇博客主要讲的是事件的使用。具体原则略述。稍微有点知识的可以看看源码[yii\base\组件yii\base\Event]就明白了。由于水平有限,欢迎朋友们交流指正。
