码迷,mamicode.com
首页 > 其他好文 > 详细

Yii源码阅读笔记(七)

时间:2016-04-16 07:11:33      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

接上次的组件(component)代码:

  1 /**
  2      * Returns a list of behaviors that this component should behave as.
  3      * 定义该对象中要用到的 behavior,返回一个行为列表
  4      * Child classes may override this method to specify the behaviors they want to behave as.
  5      *
  6      * 行为配置数组格式如下:
  7      *
  8      * ```php
  9      * ‘behaviorName‘ => [
 10      *     ‘class‘ => ‘BehaviorClass‘,
 11      *     ‘property1‘ => ‘value1‘,
 12      *     ‘property2‘ => ‘value2‘,
 13      * ]
 14      * ```
 15      * Behaviors declared in this method will be attached to the component automatically (on demand).
 16      * 定义该对象中要用到的 behavior
 17      * @return array 行为配置.
 18      */
 19     public function behaviors()
 20     {
 21         return [];
 22     }
 23 
 24     /**
 25      * Returns a value indicating whether there is any handler attached to the named event.
 26      * 判断 _events 中的一个 event 是否具有事件处理程序
 27      * @param string $name 事件名
 28      * @return boolean whether there is any handler attached to the event.
 29      */
 30     public function hasEventHandlers($name)
 31     {
 32         $this->ensureBehaviors();
 33         //短路写法,判断调用_events中是否有$name事件,没有直接返回false,否则,调用Event类中的的方法判断是否有处理程序
 34         return !empty($this->_events[$name]) || Event::hasHandlers($this, $name);
 35     }
 36 
 37     /**
 38      * Attaches an event handler to an event.
 39      * 添加事件处理程序到事件
 40      * The event handler must be a valid PHP callback. The following are
 41      * some examples:
 42      * 事件处理程序必须是有效的PHP回调函数,方便内置方法call_user_fucn()调用 ,例如:
 43      * ```
 44      * function ($event) { ... }         // 匿名函数
 45      * [$object, ‘handleClick‘]          // 以数组形式表示的对象的方法
 46      * [‘Page‘, ‘handleClick‘]           // 静态方法
 47      * ‘handleClick‘                     // 全局函数,只写函数名
 48      * ```
 49      *
 50      * The event handler must be defined with the following signature,
 51      * 时间处理程序的定义格式:
 52      * ```
 53      * function ($event)
 54      * ```
 55      *
 56      * where `$event` is an [[Event]] object which includes parameters associated with the event.
 57      * `$event`是一个包含于event相关联的[[Event]]对象
 58      * @param string $name 事件名
 59      * @param callable $handler 事件处理函数
 60      * @param mixed $data the data to be passed to the event handler when the event is triggered.
 61      * When the event handler is invoked, this data can be accessed via [[Event::data]].
 62      * @param boolean $append whether to append new event handler to the end of the existing
 63      * handler list. If false, the new handler will be inserted at the beginning of the existing
 64      * handler list.
 65      * @see off()
 66      */
 67     public function on($name, $handler, $data = null, $append = true)
 68     {
 69         $this->ensureBehaviors();//确保所有的行为都加载到组件中
 70         if ($append || empty($this->_events[$name])) {//$append 判断是否添加到事件(event)的后面,且确保_events中有该事件
 71             $this->_events[$name][] = [$handler, $data];//将事件处理程序和参数添加到event数组中
 72         } else {//否则,添加到event数组的前面
 73             array_unshift($this->_events[$name], [$handler, $data]);
 74         }
 75     }
 76 
 77     /**
 78      * Detaches an existing event handler from this component.
 79      * This method is the opposite of [[on()]].
 80      * 
 81      * [[on()]]方法的反方法,用于删除事件处理程序
 82      * 
 83      * @param string $name 事件名
 84      * @param callable $handler 事件处理程序
 85      * 如果$handler 为空,清除该事件的所有时间处理程序
 86      * @return boolean if a handler is found and detached
 87      * @see on()
 88      */
 89     public function off($name, $handler = null)
 90     {
 91         $this->ensureBehaviors();//确保所有的行为都加载到组件中
 92         if (empty($this->_events[$name])) {//如果_events中没有该事件,也就是事件不存在
 93             return false;                 //返回false
 94         }
 95         if ($handler === null) {//如果事件处理程序为空
 96             unset($this->_events[$name]);//清除该事件的所有事件处理程序
 97             return true; //返回true
 98         } else {
 99             $removed = false; //删除标记
100              //否则遍历该事件 根据on()方法的格式可以知道,$event[0]是事件处理程序,$event[1]是数据
101             foreach ($this->_events[$name] as $i => $event) {
102                 if ($event[0] === $handler) {//判断事件处理程序是否符合
103                     unset($this->_events[$name][$i]);//删除该事件处理程序
104                     $removed = true;
105                 }
106             }
107             if ($removed) {//判断是否删除成功
108                 //如果删除成功,调用array_values方法重新赋值,格式化索引
109                 $this->_events[$name] = array_values($this->_events[$name]);
110             }
111             return $removed;//返回删除成功标记
112         }
113     }
114 
115     /**
116      * Triggers an event.
117      * This method represents the happening of an event. It invokes
118      * all attached handlers for the event including class-level handlers.
119      * 
120      * 触发器方法
121      * 
122      * @param string $name 事件名
123      * @param Event $event  事件参数. 如果未设置,一个默认的 [[Event]] 对象将被创建.
124      */
125     public function trigger($name, Event $event = null)
126     {
127         $this->ensureBehaviors();
128         if (!empty($this->_events[$name])) {
129             if ($event === null) {
130                // 构建Event对象,为传入到handler函数中做准备
131                 $event = new Event;
132             }
133             if ($event->sender === null) {
134                 $event->sender = $this;
135             }
136             $event->handled = false;
137             $event->name = $name;
138             foreach ($this->_events[$name] as $handler) {
139                 //遍历_events取得处理程序名和数据
140                 $event->data = $handler[1];//给[[Event]] 的data属性赋值
141                 call_user_func($handler[0], $event);//通过内置函数call_user_func()调用事件处理函数,$event作为参数
142                 // stop further handling if the event is handled
143                 // 事件是否被handle,当handled被设置为true时,执行到这个event的时候,会停止,并忽略剩下的event--不太明白,以后追加吧
144                 if ($event->handled) {
145                     return;
146                 }
147             }
148         }
149         // invoke class-level attached handlers
150         //[[Event]] 的静态方法,触发类级别的事件处理程序
151         Event::trigger($this, $name, $event);
152     }
153 
154     /**
155      * Returns the named behavior object.
156      * 获取行为类
157      * @param string $name the behavior name
158      * @return null|Behavior the behavior object, or null if the behavior does not exist
159      */
160     public function getBehavior($name)
161     {
162         $this->ensureBehaviors();
163         return isset($this->_behaviors[$name]) ? $this->_behaviors[$name] : null;//_behaviors中的行为类存在,返回行为类名,否则返回空
164     }
165 
166     /**
167      * Returns all behaviors attached to this component.
168      * 
169      * 获取所有的行为类
170      * @return Behavior[] list of behaviors attached to this component
171      */
172     public function getBehaviors()
173     {
174         $this->ensureBehaviors();
175         return $this->_behaviors;//直接返回了_behaviors
176     }
177 
178     /**
179      * Attaches a behavior to this component.
180      * 添加一个行为到组件
181      * 通过提供的配置文件创建一个Behavior对象,通过调用 [[Behavior::attach()]] 方法添加行为到组件.
182      * @param string $name the name of the behavior.
183      * @param string|array|Behavior $behavior 行为配置,可选项如下:
184      *
185      *  - 一个行为类
186      *  - 一个字符串形式的指定行为类
187      *  - 一个配置文件数组,通过调用[[Yii::createObject()]] 创建一个行为对象.
188      *
189      * @return Behavior the behavior object
190      * @see detachBehavior()
191      */
192     public function attachBehavior($name, $behavior)
193     {
194         $this->ensureBehaviors();
195         return $this->attachBehaviorInternal($name, $behavior);
196     }
197 
198     /**
199      * Attaches a list of behaviors to the component.
200      * 添加行为到组件
201      * 行为类通过行为名索引,且必须是一个 [[Behavior]] 对象指定的行为类或者一个配置数组 
202      * 
203      * @param array $behaviors list of behaviors to be attached to the component
204      * @see attachBehavior()
205      */
206     public function attachBehaviors($behaviors)
207     {
208         $this->ensureBehaviors();
209         foreach ($behaviors as $name => $behavior) {
210             $this->attachBehaviorInternal($name, $behavior);
211         }
212     }
213 
214     /**
215      * Detaches a behavior from the component.
216      * 从组件解除行为
217      * The behavior‘s [[Behavior::detach()]] method will be invoked.
218      * 实现方式是调用Behavior类中的detach()方法
219      * @param string $name the behavior‘s name.
220      * @return null|Behavior the detached behavior. Null if the behavior does not exist.
221      */
222     public function detachBehavior($name)
223     {
224         $this->ensureBehaviors();
225         if (isset($this->_behaviors[$name])) {
226             $behavior = $this->_behaviors[$name];
227             unset($this->_behaviors[$name]);
228             $behavior->detach();
229             return $behavior;
230         } else {
231             return null;
232         }
233     }
234 
235     /**
236      * Detaches all behaviors from the component.
237      * 解除所有的行为
238      */
239     public function detachBehaviors()
240     {
241         $this->ensureBehaviors();
242         foreach ($this->_behaviors as $name => $behavior) {
243             $this->detachBehavior($name);
244         }
245     }
246 
247     /**
248      * Makes sure that the behaviors declared in [[behaviors()]] are attached to this component.
249      * 确保定义的行为都被添加到组件
250      */
251     public function ensureBehaviors()
252     {
253         if ($this->_behaviors === null) {// 如果$this->_behaviors为空
254             $this->_behaviors = [];
255             foreach ($this->behaviors() as $name => $behavior) {//遍历$this->behaviors()中的behaviors,并存储到$this->_behaviors数组中
256                 $this->attachBehaviorInternal($name, $behavior);
257             }
258         }
259     }
260 
261     /**
262      * Attaches a behavior to this component.
263      *  私有方法  添加一个行为到组件
264      * @param string|integer $name 行为名. 如果是整数,说明该行为是匿名的
265      * @param string|array|Behavior $behavior the behavior to be attached
266      * @return Behavior the attached behavior.
267      */
268     private function attachBehaviorInternal($name, $behavior)
269     {
270         if (!($behavior instanceof Behavior)) {
271             // $behavior不是Behavior对象,就认为是配置,通过它创建一个
272             $behavior = Yii::createObject($behavior);
273         }
274         if (is_int($name)) {//行为名师整数
275             $behavior->attach($this);//绑定行为到组件
276             $this->_behaviors[] = $behavior;
277         } else {
278             if (isset($this->_behaviors[$name])) {
279                 // 如果有同名的行为存在就先解绑掉
280                 $this->_behaviors[$name]->detach();
281             }
282             $behavior->attach($this);//重新绑定行为到组件
283             $this->_behaviors[$name] = $behavior;
284         }
285         return $behavior;
286     }

 

Yii源码阅读笔记(七)

标签:

原文地址:http://www.cnblogs.com/isleep/p/5397525.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!