继续解读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);
}
来源:https://www.cnblogs.com/taokai/p/5401260.html