继续解读Object.php
/** * Calls the named method which is not a class method. * * Do not call this method directly as it is a PHP magic method that * will be implicitly called when an unknown method is being invoked. * @param string $name the method name * @param array $params method parameters * @throws UnknownMethodException when calling unknown method * @return mixed the method return value */ public function __call($name, $params) { throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()"); } /** * Returns a value indicating whether a property is defined. * A property is defined if: * * - the class has a getter or setter method associated with the specified name * (in this case, property name is case-insensitive); * - the class has a member variable with the specified name (when `$checkVars` is true); * * 检查对象或类是否具有 $name 属性,如果 $checkVars 为 true,则不局限于是否有 getter/setter * * @param string $name the property name * @param boolean $checkVars whether to treat member variables as properties * @return boolean whether the property is defined * @see canGetProperty() * @see canSetProperty() */ public function hasProperty($name, $checkVars = true) { return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false); } /** * Returns a value indicating whether a property can be read. * A property is readable if: * * - the class has a getter method associated with the specified name * (in this case, property name is case-insensitive); * - the class has a member variable with the specified name (when `$checkVars` is true); * * 检查对象或类是否能够获取 $name 属性,如果 $checkVars 为 true,则不局限于是否有 getter * * @param string $name the property name * @param boolean $checkVars whether to treat member variables as properties * @return boolean whether the property can be read * @see canSetProperty() */ public function canGetProperty($name, $checkVars = true) { return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name); } /** * Returns a value indicating whether a property can be set. * A property is writable if: * * - the class has a setter method associated with the specified name * (in this case, property name is case-insensitive); * - the class has a member variable with the specified name (when `$checkVars` is true); * * * @param string $name the property name * @param boolean $checkVars whether to treat member variables as properties * @return boolean whether the property can be written * @see canGetProperty() */ public function canSetProperty($name, $checkVars = true) { return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name); } /** * Returns a value indicating whether a method is defined. * * The default implementation is a call to php function `method_exists()`. * You may override this method when you implemented the php magic method `__call()`. * * * @param string $name the method name * @return boolean whether the method is defined */ public function hasMethod($name) { return method_exists($this, $name); } }(Object.php完结)
接下来接续了解Component.php
/** * Returns a value indicating whether there is any handler attached to the named event. * * 判断 _events 中的一个 event 是否具有 handler * @param string $name the event name * @return boolean whether there is any handler attached to the event. */ public function hasEventHandlers($name) { $this->ensureBehaviors(); // _events 中存在 $name 的 event 或者 $name 的 event 是否含有该对象所在的类的 handler return !empty($this->_events[$name]) || Event::hasHandlers($this, $name); } /** * Detaches an existing event handler from this component. * This method is the opposite of [[on()]].
*拆离此组件现有的事件处理程序。 * @param string $name event name * @param callable $handler the event handler to be removed. * If it is null, all handlers attached to the named event will be removed. * @return boolean if a handler is found and detached * @see on() */ public function off($name, $handler = null) { // 保证 behaviors 都加载进来了 $this->ensureBehaviors(); // 相应的事件不存在,就返回false if (empty($this->_events[$name])) { return false; } // 没有handler,就意味着要全部去掉 if ($handler === null) { unset($this->_events[$name]); return true; } else { $removed = false; foreach ($this->_events[$name] as $i => $event) { // $event[0]是handler,$event[1]是数据 if ($event[0] === $handler) { unset($this->_events[$name][$i]); $removed = true; } } if ($removed) { // 如果有移出事件的handler,就需要重新构建以下索引,否则会出现index为1,3,4的情况 $this->_events[$name] = array_values($this->_events[$name]); } return $removed; } } /** * Triggers an event.
*触发事件 * This method represents the happening of an event. It invokes * all attached handlers for the event including class-level handlers.
*这种方法代表事件的发生,他会触发所有连接的处理程序,包括类级别处理该事件。 * @param string $name the event name * @param Event $event the event parameter. If not set, a default [[Event]] object will be created. */ public function trigger($name, Event $event = null) { // 保证 behaviors 都加载进来了 $this->ensureBehaviors(); if (!empty($this->_events[$name])) { // 构建Event对象,为传入到handler函数中做准备 if ($event === null) { $event = new Event; } if ($event->sender === null) { $event->sender = $this; } $event->handled = false; $event->name = $name; foreach ($this->_events[$name] as $handler) { // 给event的data属性赋值 $event->data = $handler[1]; // handler的函数中传入了一个Event对象 call_user_func($handler[0], $event); // stop further handling if the event is handled // 事件是否被handle,当handled被设置为true时,执行到这个event的时候,会停止,并忽略剩下的event if ($event->handled) { return; } } } // invoke class-level attached handlers // 触发class级别的handler Event::trigger($this, $name, $event); }