Yii2 事件学习笔记

Yii2中事件一般用event表示,只有集成了yii\base\component的对象才能集成类或者对象级别的事件处理过程。
事件的理解和使用要点主要有以下几个要点:
1.事件如何触发?
2.事件处理器是什么?
3.事件级别分为哪几个?
4.如何把事件处理器(handle)绑定到事件上?
5.如何解绑handle?
6.事件处理器的执行顺序?
7.事件常见用途
 
1.事件触发
调用 yii\base\Component::trigger() 方法触发,通常会在类内部某个方法里调用,如下:
namespace app\components;

use yii\base\Component;
use yii\base\Event;

class Foo extends Component
{
    const EVENT_HELLO = 'hello';

    public function bar()
    {
        $this->trigger(self::EVENT_HELLO);
    }
}

 

2.事件处理器 Event Handlers
事件处理器是一个PHP 回调函数,参数是一个event对象。
下面复习一下回调函数的一般写法:
①.匿名函数 function($event){
}
②.某个对象的方法
[$obj,'方法名称']
③.类的静态防范
[static::className(),'静态方法名']
④.全局函数,这种情况比较少一点,
'全局方法名'
 
3.事件级别
官方文档没有强调这个,可以大致分为3个级别:
①对象级别,对于某个对象的事件触发,参考1中的例子
②类级别事件处理,
如果想对某一类对象不想一个个的附加事件处理,可以在类级别直接绑定,使用方法如下。
调用yii\base\Event的on方法
Event::on(静态类名,静态类事件,事件处理器);
use Yii;
use yii\base\Event;
use yii\db\ActiveRecord;
 
Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
  Yii::trace(get_class($event->sender) . ' is inserted');
});

 

③全局事件绑定以及处理
全局应用即Yii::$app,全局应用是个单例对象,可以使用对象的事件绑定方法
第一步,在应用入口脚本:
Yii::$app->on('bar', function ($event) {
    echo get_class($event->sender); // 显示 "app\components\Foo"
});

 

第二步:埋点,在需要的地方进行触发
Yii::$app->trigger('bar', new Event(['sender' => new Foo]));
这里的触发器的第二个参数表示可以定义事件对象的一些属性,
name:事件名
sender:调用 trigger() 方法的对象
data:附加事件处理器时传入的数据,默认为空
 
4.如何把事件处理器(handle)绑定到事件上?
一般而言,调用类或者对象的on方法即可,但是对于类或者对象的on方法的参数会有一些不一样。
 
5.如何解绑handle?
解绑发方法为off,与4中on的使用类似。
 
6.事件处理器的执行顺序?
事件处理器将按附加次序依次调用,默认新附加的事件处理器排在已存在处理器队列的最后。
特殊情况如果需要优先调用则可以在on函数中传递第四个参数为false,即可第一个调用。如下所示:
$foo->on(Foo::EVENT_HELLO, function ($event) {
// 这个处理器将被插入到处理器队列的第一位...
}, $data, false);

 

7.经典用法
事件的用途比较多,常见的用途是记录日志,
如记录全局的代码级别的操作日志,数据库的更新操作日志等等。
①记录全局访问日志的写法:
在配置文件中假如如下配置: 'on beforeRequest' => handle;
②记录数据库更新操作
第一步,在配置文件新增行为配置:'as adminLog' => 'app\\behaviors\\AdminDbLogBehavior';
第二部,在yii\db\command类中埋点,比如在execute中:
const EVENT_EXECUTE = 'execute';
public function execute()
{
    $this->trigger(self::EVENT_EXECUTE);
    .....other code
}

 

第三步,在AdminDbLogBehavior.php中进行事件绑定,并指定事件处理器,在事件处理器中进行具体的记录操作,代码类似如下:
 
namespace frontend\behaviors;

use Yii;
use yii\base\Application;
use yii\base\Behavior;
use yii\base\Event;
use yii\db\Command;

class AdminLogBehavior extends Behavior
{
    public function events()
    {
        return [
            Application::EVENT_BEFORE_REQUEST => 'handle'
        ];
    }
    
    public function handle()
    {
        Event::on(Command::className(),  Command::EVENT_EXECUTE,[$this,'log']);
    }

    public function log($event)
    {
        //具体的记录操作,
        //如果是记录db更新操作那么不要直接记录到当前数据库,否则会引起循环记录
    }
}      

 

 
 
 
 
 
 
posted @ 2018-03-20 20:16  lc_vip_000  阅读(307)  评论(0编辑  收藏  举报