使用事件
Yii的时间提供了一个简单的实现, 它允许你监听订阅发生在你web应用中各种各样的事件。例如,你也许希望发送一个通知:每次当你发布一个新材料时,将这个新文档通知到你的订阅者。
准备
- 按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。
- 在你的服务器上执行如下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;
- 使用Gii生成Article模型。
- 使用./yii服务命令运行你的web服务器。
如何做…
- 添加一个测试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 = ['john2@teleworm.us',
'shivawhite@cuvox.de', 'kate@dayrep.com' ];
foreach($followers as $follower) {
Yii::$app->mailer->compose()
->setFrom('techblog@teleworm.us')
->setTo($follower)
->setSubject($event->sender->name)
->setTextBody($event->sender->description)
->send();
}
echo 'Emails has been sent';
});
if (!$article->save()) {
echo VarDumper::dumpAsString($article->getErrors());
};
}
- 使用如下代码更新config/web.php控件mailer:
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'useFileTransport' => false,
],
- 在你的浏览器中访问如下网址:
http://localhost:8080/index.php?r=site/test.
工作原理…
我们已经创建了一个Article模型,并在Article模型中为ActiveRecord::EVENT_AFTER_INSERT事件添加了一个handler。它意味着我们每次保存一个新文章,这个事件都会被触发,然后我们的handler就会被调用。
在现实世界中,我们也许希望在我们每次发布一个新文章时,通知我们的博客订阅者。在一个实际应用中,我们将会有一个follower或者user表,and with different blog sections not only single blog。在这个例子中,在保存好我们的模型以后,我们通知了我们的订阅者john2@teleworm.us
、shivawhite@cuvox.de
和kate@dayrep.com
。在上一步中,我们只是证明了用户已经收到了我们的通知,特别是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 = ['john2@teleworm.us', 'shivawhite@cuvox.de',
'kate@dayrep.com' ];
foreach($followers as $follower) {
Yii::$app->mailer->compose()
->setFrom('techblog@teleworm.us')
->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