使用事件

Yii的时间提供了一个简单的实现, 它允许你监听订阅发生在你web应用中各种各样的事件。例如,你也许希望发送一个通知:每次当你发布一个新材料时,将这个新文档通知到你的订阅者。

准备

  1. 按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。
  2. 在你的服务器上执行如下SQL代码,创建文章表:
CREATE TABLE 'article' (
    'id' int(11) NOT NULL AUTO_INCREMENT,
    'name' varchar(255) DEFAULT NULL,
    'description' text,
    PRIMARY KEY ('id')
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
  1. 使用Gii生成Article模型。
  2. 使用./yii服务命令运行你的web服务器。

如何做...

  1. 添加一个测试action到\controllers\SiteController:
<?php
public function actionTest()
{
    $article = new Article();
    $article->name = 'Valentine\'s Day\'s coming? Aw crap! I forgot to get a girlfriend again!';
    $article->description = 'Bender is angry at Fry for dating a robot. Stay away from our women. You\'ve got metal fever, boy. Metal fever';
    // $event is an object of yii\base\Event or a child class
    $article->on(ActiveRecord::EVENT_AFTER_INSERT,
        function($event) {
            $followers = ['[email protected]',
                '[email protected]', '[email protected]' ];
            foreach($followers as $follower) {
                Yii::$app->mailer->compose()
                    ->setFrom('[email protected]')
                    ->setTo($follower)
                    ->setSubject($event->sender->name)
                    ->setTextBody($event->sender->description)
                    ->send();
            }
            echo 'Emails has been sent';
        });
    if (!$article->save()) {
        echo VarDumper::dumpAsString($article->getErrors());
    };
}
  1. 使用如下代码更新config/web.php控件mailer:
'mailer' => [
    'class' => 'yii\swiftmailer\Mailer',
    'useFileTransport' => false,
],
  1. 在你的浏览器中访问如下网址:

http://localhost:8080/index.php?r=site/test.

  1. 另外检查http://www.fakemailgenerator.com/inbox/teleworm.us/john2/

工作原理...

我们已经创建了一个Article模型,并在Article模型中为ActiveRecord::EVENT_AFTER_INSERT事件添加了一个handler。它意味着我们每次保存一个新文章,这个事件都会被触发,然后我们的handler就会被调用。

在现实世界中,我们也许希望在我们每次发布一个新文章时,通知我们的博客订阅者。在一个实际应用中,我们将会有一个follower或者user表,and with different blog sections not only single blog。在这个例子中,在保存好我们的模型以后,我们通知了我们的订阅者[email protected][email protected][email protected]。在上一步中,我们只是证明了用户已经收到了我们的通知,特别是john2。你可以用任意名称创建你自己的事件,这里我们使用了一个内置的事件,叫做ActiveRecord::EVENT_AFTER_INSERT,它会在每次插入到数据库中调用。

例如,我们可以创建我们自己的事件。只需要使用如下代码添加一个新的actionTestNew:

<?php
public function actionTestNew()
{
    $article = new Article();
    $article->name = 'Valentine\'s Day\'s coming? Aw crap! I forgot to get a girlfriend again!';
    $article->description = 'Bender is angry at Fry for dating a robot. Stay away from our women. You\'ve got metal fever, boy. Metal fever';
// $event is an object of yii\base\Event or a child class
    $article->on(Article::EVENT_OUR_CUSTOM_EVENT, function($event) {
        $followers = ['[email protected]', '[email protected]',
            '[email protected]' ];
        foreach($followers as $follower) {
            Yii::$app->mailer->compose()
                ->setFrom('[email protected]')
                ->setTo($follower)
                ->setSubject($event->sender->name)
                ->setTextBody($event->sender->description)
                ->send();
        }
        echo 'Emails have been sent';
    });
    if ($article->save()) {
        $article->trigger(Article::EVENT_OUR_CUSTOM_EVENT);
    }
}

同时按照如下方式将EVENT_OUR_CUSTOM_EVENT常量加入到模型models/Article中:

class Article extends \yii\db\ActiveRecord
{
    CONST EVENT_OUR_CUSTOM_EVENT = 'eventOurCustomEvent';
    …
}

访问http://localhost:8080/index.php?r=site/test-new。

你应该看到相同的结果,并且所有给订阅者的通知会再发一遍。主要的区别是我们使用了自定义的事件名。

保存以后,我们触发了我们的事件。事件是通过调用yii\base\Component::trigger()触发的。这个方法需要一个事件名称,以及一个可选的事件对象,它描述了传递给事件handler的参数。

参考

欲了解更多信息参见http://www.yiiframework.com/doc-2.0/guide-conceptevents.
html

results matching ""

    No results matching ""