一:事件
事件可以将自定义代码“注入”到现有代码中的特定执行点。 附加自定义代码到某个事件,当这个事件被触发时,这些代码就会自动执行,例如当我们向数据库的一个表中新增数据时,如果你想要在新增数据之前或新增数据之后执行指定的操作的话,这时候我们就可以使用事件来实现
如:
在表对应的模型的init方法中添加:
//新增数据之前事件,处理器是对象方法
$this->on(Country::EVENT_BEFORE_INSERT, [$this, 'function_name']);
//新增数据之后,处理器是匿名函数
$this->on(Country::EVENT_AFTER_INSERT,function ($event) {
echo '新增数据之后';
});
处理器是对象方法的在模型中新增一个function_name方法,该方法为当指定事件触发时执行
public function function_name($event)
{
echo '新增数据之前';
}
事件处理器调用yiibaseComponent::on() 方法来附加处理器到事件上,该方法的第三个参数的数据,在在事件被触发和处理器被调用时能被处理器使用
可以使用如下方法获取
$event->data
在模型中在事件触发后我们可以使用如下获取对应的表数据
$event->sender
如果你想要在执行指定的事件处理器之后,停止后续的事件处理器调用,可以设置 $event 参数的 yii\base\Event::$handled 属性为真,这时候这个事件处理器之后的处理器都不会再执行了
$event->handled = true;
如果你想要将指定的事件触发器在事件触发之后第一个执行的话,可以在调用yiibaseComponent::on()方法时将第四个参数设置为false
$this->on(Country::EVENT_AFTER_INSERT,function ($event) {
echo '新增数据之后';
}, null, false);
上面我们使用的触发事件都是Yii创建写好的现成事件,如果我们想要自己写一个事件的话,如下:
这里我创建一个EVENT_HELLO事件
const EVENT_HELLO = 'hello';
//当执行sayHello时触发hello事件
public function sayHello()
{
$this->trigger(self::EVENT_HELLO);
}
如上我们创建了一个触发事件,当我们调用sayHello方法后,这时候我们会触发一个名为hello的事件
调用:
$this->sayHello();
事件处理器:
$this->on(self::EVENT_HELLO, function ($event) {
echo 111;
});
如上,当我们调用sayHello方法后,这时候页面上会输出111
二:行为
1:创建行为类:
行为是 yiibaseBehavior或其子类的实例,可以无须改变类继承关系即可增强一个已有的组件类功能,当行为附加到组件后,它将“注入”它的方法和属性到组件,,然后可以像访问组件内定义的方法和属性一样访问它们
如下定义了一个行为
<?php
namespace frontend\behavior;
use yii\base\Behavior;
class TestBehavior extends Behavior
{
/**
* 内部属性message
*/
private $_message;
/**
* 获取message属性
*/
public function getMessage()
{
return $this->_message;
}
/**
* 设置message属性
*/
public function setMessage($value)
{
$this->_message = $value;
}
}
如上就是一个最简单的行为类,我们还可以让行为类来相应对应组件的事件触发,这时候我们可以复写yiibaseBehavior::events() 方法
如下创建了一个用户在新增和更新数据之前执行的行为类
<?php
namespace frontend\behavior;
use yii\base\Behavior;
use yii\db\ActiveRecord;
class TestBehavior extends Behavior
{
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeUpdate',
ActiveRecord::EVENT_BEFORE_INSERT => 'beforeInsert',
];
}
public function beforeUpdate($event)
{
//业务代码
}
public function beforeInsert($event)
{
//业务代码
}
}
2:附件行为类(使用行为类)
我们可以静态或动态地附加行为到组件
(1):静态附加行为类
要静态附加行为,覆写行为要附加的组件类的behaviors()方法即可。 behaviors()方法应该返回行为配置列表。 每个行为配置可以是行为类名也可以是配置数组
如:
public function behaviors()
{
return [
// 匿名行为,只有行为类名
TestBehavior::className(),
// 命名行为,只有行为类名
'testBehavior' => TestBehavior::className(),
// 匿名行为,配置数组
[
'class' => TestBehavior::className(),
'message' => 'value1',
],
// 命名行为,配置数组
'myBehavior4' => [
'class' => TestBehavior::className(),
'message' => 'value1',
]
];
}
(2):动态附加行为类
要动态附加行为,在对应组件里调用 yiibaseComponent::attachBehavior() 方法即可
// 附加行为对象
$this->attachBehavior('testBehavior', new TestBehavior());
// 附加行为类
$this->attachBehavior('testBehavior', TestBehavior::className());
// 附加配置数组
$this->attachBehavior('testBehavior', [
'class' => TestBehavior::className(),
'message' => 'value1',
]);
//一次附加多个行为类
$this->attachBehaviors([
'testBehavior' => new TestBehavior, // 命名行为
TestBehavior::className(), // 匿名行为
]);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。