YII2.0框架行为(Behavior)深入详解(8)

public function events()
{
 return array_fill_keys(array_keys($this->attributes),
  'evaluateAttributes');
}

这段代码的意思这里不作过多深入,学有余力的读者朋友可以自行研究,难度并不高。 这里,你只需要大致知道,这段代码将返回一个数组,其键值为 $this->attributes 数组的键值, 数组元素的值为成员函数evaluateAttributes 。

而在 yii\behaviors\TimeStampBehavior::init() 中,有以下的代码:

public function init()
{
 parent::init();
 if (empty($this->attributes)) {
  // 重点看这里
  $this->attributes = [
   BaseActiveRecord::EVENT_BEFORE_INSERT =>
    [$this->createdAtAttribute, $this->updatedAtAttribute],
   BaseActiveRecord::EVENT_BEFORE_UPDATE =>
    $this->updatedAtAttribute,
  ];
 }
}

上面的代码重点看的是对于 $this->attributes 的初始化部分。 结合上面2个方法的代码,对于yii\base\Behavior::events() 的返回数组,其格式应该是这样的:

return [
 BaseActiveRecord::EVENT_BEFORE_INSERT => 'evaluateAttributes',
 BaseActiveRecord::EVENT_BEFORE_UPDATE => 'evaluateAttributes',
];

数组的键值用于指定要响应的事件, 这里是 BaseActiveRecord::EVENT_BEFORE_INSERTBaseActiveRecord::EVENT_BEFORE_UPDATE 。 数组的值是一个事件handler,如上面的 evaluateAttributes 。

那么一旦TimeStampBehavior与某个ActiveRecord绑定,就会调用 yii\behaviors\TimeStampBehavior::attach() , 那么就会有:

// 这里 $owner 是某个 ActiveRecord
public function attach($owner)
{
 $this->owner = $owner;
 // 遍历上面提到的 events() 所定义的数组
 foreach ($this->events() as $event => $handler) {
  // 调用 ActiveRecord::on 来绑定事件
  // 这里 $handler 为字符串 `evaluateAttributes`
  // 因此,相当于调用 on(BaseActiveRecord::EVENT_BEFORE_INSERT,
  // [$this, 'evaluateAttributes'])
  $owner->on($event, is_string($handler) ? [$this, $handler] :
   $handler);
 }
}

因此,事件 BaseActiveRecord::EVENT_BEFORE_INSERTBaseActiveRecord::EVENT_BEFORE_UPDATE 就绑定到了ActiveRecord上了。当新建记录或更新记录时, TimeStampBehavior::evaluateAttributes 就会被触发。 从而实现时间戳的功能。具体可以看看 yii\behaviors\AttributeBehavior::evaluateAttributes()yii\behaviors\TimeStampBehavior::getValues() 的代码。这里因为只是具体功能实现,对于行为的理解关系不大。 就不把代码粘出来占用篇幅了。

行为的属性和方法注入原理

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/5482.html