码农日记

薄洪涛的个人博客

Yii2.0中事件的使用及理解

    Yii 三大特性:属性,事件,行为;这篇文章咱们讲讲Yii事件;

    事件是代码解耦的一种方式,设计业务流程的一种模式。

    在yii2.0中,通过Yii\base\Component继承yii\base\Object,重载__get()、__set()方法,引入了事件和行为,使得开发变得十分方便。

说一下什么叫做Yii中的事件

    文档定义:事件可以将自定义代码“注入”到现有代码中的特定执行点。 附加自定义代码到某个事件,当这个事件被触发时,这些代码就会自动执行。 例如,邮件程序对象成功发出消息时可触发 messageSent 事件。 如想追踪成功发送的消息,可以附加相应追踪代码到 messageSent 事件。

其实就是说,事件可以理解成一个触发器,里面定义了一些动作,当这个事件被触发的时候,动作执行

    我举个栗子来说明下事件的用法,以我之前写的博客CMS为例,当我删除文章的时候,把删除日志追加到日志中,删除文章这是一个触发点,追加到日志是事件;有人说,这么简单的功能为什么用事件呢,if判断不就好了,if(文章删除) 追加到日志;那请你看下事件的定义,注入到现有代码,解耦;就是说,不修改现有代码;如果不仅仅是追加到日志,删除文章后有更多的动作要执行,那你的代码需要追加多少if ?

看代码:

ArticleController中的代码

//定义事件的名字
const EVENT_DEL_ARTICLE = "del_article";
//绑定事件
public function __construct()
{
  $this->on(self::EVENT_DEL_ARTICLE,['app\models\Operlog','logdel'])
}


Operlog模型中的代码:

public static function logdel($event){
  recordLog("这是触发事件插入的日志信息",2);
}
在文章控制器ArticleController中,定义了事件的名字,在构造方法中我们绑定事件,就是说,del_article这个事件要调用app\models\Operlog中的logdel这个方法,其中recordLog是我封装的一个添加message到数据库中的一个方法
事件的定义和声明咱们已经完成了,现在就要去触发事件了
看代码

ArticleController中的删除文章函数:

public function actionDel()
{
    if (Yii::$app->request->isAjax) {
        $id = Yii::$app->request->post('id', '');
        $this->returnJson();
        if ($id && Article::updateAll(['status' => 0], ['id' => $id])){
            $key = Article::find()->where(['id'=>$id])->select('article_title')->scalar();
            recycler($id,'app\models\Article','文章',$key);
            $this->trigger(self::EVENT_DEL_ARTICLE);
            return ['code' => 200];
        }else{
            return ['code' => 0, 'msg' => '删除失败'];
        }
    }
}
可以看到,在del方法中,有句 $this->trigger(self::EVENT_DEL_ARTICLE);这句话就是触发事件;

当我们删除谋篇文章,执行到Del方法时,事件被触发,会向数据库中插入日志信息

TIM截图20181102115400.png


另外,如果想传递参数要怎么办呢


可以在@app下新建一个events文件夹,新建一个类叫做LogEvent.php(当然Operlog要继承Event)当做信使去传递参数

代码如下

namespace app\events;
use yii\base\Event;

class LogEvent extends Event
{
    public $article_id = 0;
}

修改事件方法如下

public static function logdel($event){
    recordLog("这是触发事件插入的日志信息,删除的文章id是".$event->article_id,2);
}


删除方法中

public function actionDel()
{
    if (Yii::$app->request->isAjax) {
        $id = Yii::$app->request->post('id', '');
        $this->returnJson();
        if ($id && Article::updateAll(['status' => 0], ['id' => $id])){
            $key = Article::find()->where(['id'=>$id])->select('article_title')->scalar();
            recycler($id,'app\models\Article','文章',$key);
            //注意这里
            $event = new LogEvent();
            $event->article_id = $id;
            $this->trigger(self::EVENT_DEL_ARTICLE,$event);
            return ['code' => 200];
        }else{
            return ['code' => 0, 'msg' => '删除失败'];
        }
    }
}

这样就可以传递参数了

TIM截图20181102130255.png

其实个人感觉事件最大的好处就是解耦,通过注入代码来减少代码的耦合

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Powered By Z-BlogPHP 1.7.3

版权所有 | 转载请标明出处