yii2项目实战-用事件优雅的发送邮件

上文我们介绍了事件的概念以及事件的基本操作,包括事件如何定义以及如何触发。

本文我们再通过一个发送邮件的案例对之加深理解。

定义邮件类

既然是发送邮件,那自然就需要有一个邮件类,专门用来发送邮件。我们在backend\components下定义一个发送邮件的Mail类

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

namespace backend\components;

use Yii;

class Mail
{
public static function sendMail ()
{
echo 'send mail...';
}
}

定义事件并触发

接着我们在backend\controllers下定义一个发送邮件的控制器SendMailController

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
<?php

namespace backend\controllers;

use Yii;
use yii\web\Controller;

/**
* 发送邮件
* @see http://www.manks.top/document/yii2-event-example.html
*/
class SendMailController extends Controller
{
const SEND_MAIL = 'send_mail';

public function init ()
{
parent::init();

// 绑定邮件类,当事件触发的时候,调用我们刚刚定义的邮件类Mail
$this->on(self::SEND_MAIL, ['backend\components\Mail', 'sendMail']);
}

public function actionSend ()
{
// 触发邮件事件
$this->trigger(self::SEND_MAIL);
}
}

具体的细节我们在上一章节都有所介绍,如果你觉得还是有那么一点稍稍不好理解的话,点击上文再看看呗。

现在我们请求下/index.php?r=send-mail/send操作,页面上输出 send mail…,这便是正常的结果了。我们来看下问题:

回想一下我们平时用qq或者163的邮箱发送邮件的步骤,是不是要填写收件人,主题和内容的呀?如果我们就这样光秃秃的触发了发送邮件的事件,我们是想要把某个固定的邮件内容发送给固定的某个人吗?这肯定不符合我们的实际需求啦!也就是说,我们需要在触发邮件的时候,带一些参数,比如邮箱,主题等信息,然后在Mail类中发送给需要接收邮件的人,对吧?

说了那么多无非是想让大家明白,在触发事件的时候,我们需要把与事件相关的一些数据传递给回调函数。很简单,只需要在调用yii\base\Component的trigger方法的第二个参数设定即可,但是这个参数有个特殊之处,必须要是yii\base\Event及其子类,这一点还请额外注意。来看具体实现:

在backend\components\event目录下创建一个MailEvent,用于传递邮箱、主题和内容参数给邮件类Mail

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

namespace backend\components\event;

use yii\base\Event;

class MailEvent extends Event
{
public $email;

public $subject;

public $content;
}

接下来便需要在调用trigger方法的地方实例化该类并把实例化的对象作为第二个参数进行传递了

1
2
3
4
5
6
7
8
9
10
public function actionSend ()
{
// 触发邮件事件
$event = new MailEvent;
$event->email = '422744746@qq.com';
$event->subject = '事件邮件测试';
$event->content = '邮件测试内容';

$this->trigger(self::SEND_MAIL, $event);
}

参数传递给了我们一开始使用on绑定事件的那个回调函数,就是我们这里的 backend\components\Mail 类的sendMail方法

我们在sendMail中先接收下传递的参数,看看是不是这样

1
2
3
4
5
6
public function sendMail ($event)
{
echo "email is {$event->email} <br>";
echo "subject is {$event->subject} <br>";
echo "content is {$event->content}";
}

访问下/index.php?r=send-mail/send ,页面上正常输出了我们在SendMailController的send操作中传递的参数,还好还好,一切ok。

在发送邮件之前,我们先对邮箱进行一下配置。

yii2中,默认集成了邮件组件,我们只需要简单的配置下就可以发送邮件了,当然我说的是advanced版本。

打开 common\config\main-local.php 文件,对组件mailer配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'mailer' => [ 
'class' => 'yii\swiftmailer\Mailer',
'viewPath' => '@common/mail',
// 这个要设置为false,才会真正的发邮件
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
// 如果是163邮箱,host改为smtp.163.com
'host' => 'smtp.qq.com',
// 邮箱登录帐号
'username' => '422744746@qq.com',
// 如果是qq邮箱,这里要填写第三方授权码,而不是你的qq登录密码,参考qq邮箱的帮助文档
//http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256
'password' => '******',
'port' => '25',
'encryption' => 'tls',
],
'messageConfig'=>[
'charset'=>'UTF-8',
'from'=>['422744746@qq.com'=>'白狼栈']
],
],

邮箱配置好了,那我们就来配置邮件类发送邮件吧,因为不是本篇文章的重点,所以这里我们简单实现下发送邮件,如果有需要,该类大家可以结合MailEvent类自行完善

1
2
3
4
5
6
7
8
9
public static function sendMail ($event)
{
$mail= Yii::$app->mailer->compose();
$mail->setTo($event->email); //要发送给那个人的邮箱
$mail->setSubject($event->subject); //邮件主题
$mail->setTextBody($event->content); //发布纯文字文本

return $mail->send();
}

此时此刻,试试你有没有收到邮件?