本文实例讲述了yii框架组件的事件机制原理与用法。分享给大家供大家参考,具体如下:
在深入分析 yii 的运行之前,我们先来看一下 yii 框架中一个很重要的机制 – 事件。
yii 官方参考文档关于组件事件的解释:
====经典广告案例分析===================================================================
组件事件是一些特殊的属性,它们使用一些称作 事件句柄 ( event handlers )的方法作为其值。 附加 ( 分配 ) 一个方法到一个事件将会引起方法在事件被唤起处自动被调用。因此, 一个组件的行为可能会被一种在部件开发过程中不可预见的方式修改。
组件事件以 on 开头的命名方式定义。和属性通过 getter/tter 方法来定义的命名方式一样, 事件的名称是大小写不敏感的。以下代码定义了一个 onclicked 事件 :
public function onclicked($event){ $this->raievent('onclicked'独的拼音, $event);}
这里作为事件参数的 $event 是 cevent 或其子类的实例。
我们可以附加一个方法到此 event ,如下所示 :
$component->onclicked=$callback;
这里的 $callback 指向了一个有效的 php 回调。它可以是一个全局函数也可以是类中的一个方法。 如果是后者,它必须以一个数组的方式提供 : array($object,’methodname’).
事件句柄的结构如下:
function methodname($event){ ......}
这里的 $event 即描述事件的参数(它来源于 raievent() 调用)。 $event 参数是 cevent 或其子类的实例。 至少,它包含了关于谁触发了此事件的信息。
从版本 1.0.10 开始,事件句柄也可以是一个 php 5.3 以后支持的匿名函数。例如,
$component->onclicked=function($event) { ......}
如果我们现在调用 onclicked() , onclicked 事件将被触发(在 onclicked() 中), 附属的事件句柄将被自动调用。
一个事件可以绑定多个句柄。当事件触发时, 这些句柄将被按照它们绑定到事件时的顺序依次执行。如果句柄决定组织后续句柄被执行,它可以设置 $event->handled 为 true 。
=======================================================================
从这一句开始”我们可以附加一个方法到此 event “,读者可能 就不知道是什么意思了,于是看一下 ccomponent 的源码:
/** * rais an event. * this method reprents the happening of an event. it invokes * all attached handlers for the event. * @param string the event name * @par七零八落什么意思am cevent the event parameter * @throws cexception if the event is undefined or an event handler is invalid. */ public function raievent($name,$event){ //事件名称同一小写化处理 $name=strtolower($name); //先查看成员变量是否有以此命名的事件 if(ist($this->_e[$name])) { //如果有,这个成员保存的是每一个事件处理器 //以数组的方式保存 foreach($this->_e[$name] as $handler) { //如果事件处理器是一个字符串,那么就是一个全局函数 if(is_string($handler)) call_ur_func($handler,$event); //如果不是,那么有可能是一个数组,该数组包含一个对象和方法名 //参考/d/file/titlepic/function.is-callable.php el if(is_callable($handler,true)) { // an array: 0 - object, 1 - method name list($object,$method)=$handler; //如果对象是一个对象名 if(is_string($object)) // static method call call_ur_func($handler,$event); //判断对象是否有要调用的方法 el if(method_exists($object,$method)) $object->$method($event); el 北京电子科技职业学院官网throw new cexception(yii::t('yii','event "{class}.{event}" is attached with an invalid handler"{handler}".', array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>$handler[1]))); } el throw new cexception(yii::t('yii','event "{class}.{event}" is attached with an invalid handler"{handler}".', array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>gettype($handler)))); // stop further handling if param.handled is t true //如果想停止继续循环获取事件的handler//那么需要设置event的handled为true if(($event instanceof cevent) && $event->handled) return; } } el if(yii_debug && !$this->havent($name)) throw new cexception(yii::t('yii','event "{class}.{event}" is not defined.', array('{class}'=>get_class($this), '{event}'=>$name))); //如果_e中没有这个成员也没关系 }
我们再看一下 cevent 的代码( ccomponent.php ):
class cevent extends ccomponent{ /** * @var object the nder of this event */ public $nder; /** * @var boolean whether the event is handled. defaults to fal. * when a handler ts this true, the rest uninvoked handlers will not be invoked anymore. */ public $handled=fal; /** * constructor. * @param mixed nder of the event */ public function __construct($nder=null) { $this->nder=$nder; }}
cevent 只包含两个变量 $nder 记录事件触发者, $handled 表示事件是否已经被“解决”。
接着我们再看一下如何给一个组件注册一个事件处理器:
/** * attaches an event handler to an event. * * an event handler must be a valid php callback, i.e., a string referring to * a global function name, or an array containing two elements with * the first element being an object and the cond element a method name * of the object. * * an event handler must be defined with the following signature, * <pre> * function handlername($event) {} * </pre> * where $event includes parameters associated with the event. * * this is a convenient method of attaching a handler to an event. * it is equivalent to the following code: * <pre> * $component->geteventhandlers($eventname)->add($eventhandler); * </pre> * * using {@link geteventhandlers}, one can also specify the excution order * of multiple handlers attaching to the same event. for example: * <pre> * $component->geteventhandlers($eventname)->inrtat(0,$eventhandler); * </pre> * makes the handler to be invoked first. * * @param string the event name * @param callback the event handler * @throws cexception if the event is not defined * @e detacheventhandler */ public function attacheventhandler($name,$handler) { $this->geteventhandlers($name)->add($handler); } /** * returns the list of attached event handlers for an event. * @param string the event name * @return clist list of attached event handlers for the event * @throws cexception if the event is not defined */ public function geteventhandlers($name) { if($this->havent($name)) { $name=strtolower($name); if(!ist($this->_e[$name])) //新建一个clist保存事件的处理器 $this->_e[$name]=new clist; return $this->_e[$name]; } el 新闻发布会主持词 throw new cexception(yii::t('yii','event "{class}.{event}" is not defined.', array('{class}'=>get_class($this), '{event}'=>$name)));}
由此可以看出,首先获取事件处理器对象,如果没有则使用 clist ( yii 实现的一个链表)创建,然后将事件处理器 add 进这个对象中,这样就可以在 raievent 时遍历所有的事件处理器进行处理了,有点儿类似 jquery 中注册了多个 click 事件处理器之后,当 click 事件触发时,会按顺序调用之前注册的事件处理器。
本文发布于:2023-04-08 16:55:04,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/1931ddda3110b25f42820d0f292100b4.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:Yii框架组件的事件机制原理与用法分析.doc
本文 PDF 下载地址:Yii框架组件的事件机制原理与用法分析.pdf
留言与评论(共有 0 条评论) |