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 继承自
