logo头像

Hello World

Yii2 Event事件-场景应用

yii2-事件 系列 第二篇


前言

通过Yii2的事件功能,为我们的项目开发带来了极大的便捷性。
本文在介绍几个比较特别的事件同时,将通过介绍几个应用场景的方式,来更贴切实际开发。

更多事件请查看Yii2速查表或我的上篇文章Yii2 Event事件-初识

EVENT_AFTER_FIND

在查询结束后,会触发EVENT_AFTER_FIND事件。
注意Yii2里没有EVENT_BEFORE_FIND事件(查询前)。

而EVENT_AFTER_FIND和其它事件不同的是

虽然该常量定义是BaseActiveRecord::EVENT_AFTER_FIND,

但是该事件触发位置由yii\db\ActiveQuery触发。具体位置

1
yii\db\ActiveQuery::populate()
  • 使用场景 文章发布日期显示2分钟前这样的格式。

    1.绑定事件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    \yii\base\Event::on(
    BaseActiveRecord::className(),
    BaseActiveRecord::EVENT_AFTER_FIND,
    function ($event){
    $model = $event->sender;
    $model->update_date = time_tran($model->update_date);
    $event->sender = $model;
    return $event;
    }
    );

    2.新建时间转换函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    function time_tran($agoTime)
    {
    $agoTime = strtotime($agoTime);
    $time = time() - $agoTime;
    if ($time >= 31104000) { // N年前
    $num = (int)($time / 31104000);
    return $num.'年前';
    }
    if ($time >= 2592000) { // N月前
    $num = (int)($time / 2592000);
    return $num.'月前';
    }
    if ($time >= 86400) { // N天前
    $num = (int)($time / 86400);
    return $num.'天前';
    }
    if ($time >= 3600) { // N小时前
    $num = (int)($time / 3600);
    return $num.'小时前';
    }
    if ($time > 60) { // N分钟前
    $num = (int)($time / 60);
    return $num.'分钟前';
    }
    return '1分钟前';
    }

EVENT_BEFORE_VALIDATE

该事件顾名思义,就是在model验证前事件。

该事件有一个很棒的特性,在触发该事件,当你的handler函数执行了一系列操作,这个时候如果你发现没有验证的必要的时候。
可以手动修改$event->isVaild = false。

后续就不会再继续验证了。可以减少一些代码执行,提高效率。

自定义事件

有许多场景可以使用到事件,比如我们在用户注册后,发送验证邮件。
下面是事例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
namespace console\controllers;

use Yii;
use yii\console\Controller;
use yii\base\Component;

class RegesiterController extends Controller
{
public function actionTest()
{
   $core = new Core();
   $user = new user();
   $user->on('regesiter', [$core, 'verifyMail']);
$student->regesiter();
}
}

class User extends Component
{
public function regesiter()
{
   echo "User regesited\n";
$this->trigger('regesiter');
}
}

class Core extends Component
{
public function verifyMail()
{
echo "Core Send E-mail to User\n";
}
}
上一篇