namespace app\Components; use yii\db\ActiveRecord; use yii\base\Behavior; class MyBehavior extends Behavior { // 重载events() 使得在事件触发时,调用行为中的一些方法 public function events() { // 在EVENT_BEFORE_VALIDATE事件触发时,调用成员函数 beforeValidate return [ ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate', ]; } // 注意beforeValidate 是行为的成员函数,而不是绑定的类的成员函数。 // 还要注意,这个函数的签名,要满足事件handler的要求。 public function beforeValidate($event) { // ... } }
上面的代码中, events()
返回一个数组,表示所要做出响应的事件, 上例中的事件是ActiveRecord::EVENT_BEFORE_VALIDATE
,以数组的键来表示, 而数组的值则表示做好反应的事件handler,上例中是beforeValidate()
,事件handler可以是以下形式:
- 字符串,表示行为类的方法,如上面的例就是这种情况。 这个是与事件handler不同的,事件handler中使用字符串时,是表示PHP全局函数,而这里表示行为类内部的方法。
- 一个对象或类的成员函数,以数组的形式,如 [$object, 'methodName'] 。这个与事件handler是一致的。
- 一个匿名函数。
对于事件响应函数的签名,要求与事件handler一样:
function ($event) { }
具体内容,请参考 事件(Event) 的内容。
行为的绑定与解除
说到绑定与解除,这意味着这个事情有2方,行为和Component。单独一方是没有绑定或解除的说法的。 因此,这里我们先卖一关子,等后面讲绑定和解除的原理时,再来讲有关的内容。
这里你只需要知道,对于绑定和解除,Behavior 分别使用 attach()
和 detach()
来实现就OK了。
定义一个行为
定义一个行为,就是准备好要注入到现有类中去的属性和方法, 这些属性和方法要写到一个 yii\base\Behavior 类中。 所以,定义一个行为,就是写一个 Behavior的子类,子类中包含了所要注入的属性和方法:
namespace app\Components; use yii\base\Behavior; class MyBehavior extends Behavior { public $prop1; private $_prop2; private $_prop3; private $_prop4; public function getProp2() { return $this->_prop2; } public function setProp3($value) { $this->_prop3 = $value; } public function foo() { // ... } protected function bar() { // ... } }
上面的代码通过定义一个 app\Components\MyBehavior 类而定义一个行为。 由于 MyBehavior 继承自