yii2.0利用yii2-swiftmailer扩展发送邮件

官方文档地址:http://www.yiichina.com/doc/guide/2.0/tutorial-mailing

昨晚在CSDN写了这篇博客,明明保存成功了,但是实际上却是搞丢了!这令我很郁闷,还是回到iteye这个虽然多年没更新过,但是可以传小附件,代码格式化也不错的博客。

做产品或项目时,我们很多时候需要给客户发邮件。比如密码重置、各种通知。

那么yii2.0自带的yii2-swiftmailer扩展当属我用过的最完美的扩展了。

不得不承认,虽然yii2.0在视图里穿插各种php代码令我崩溃,但它的设计模式的确令人咋舌,各类工具也是非常齐全。

官方文档能让我们看到这个扩展的基本用法,还是中文版的,所以我就不重复描述了。

我要说的是,在工作中,我们应该尽量抽象好这些接口,给项目或产品提供更通用、易懂、与底层无关的接口。比如这个发信的扩展,通过我们进行一层抽象,产品中调用我们适配好的接口,既可以不用关注“yii2-swiftmailer扩展”的使用方法,另外万一扩展不靠谱,我们还可以在接口中随时替换它,而不会影响到产品中的所有代码。

其实即使Yii的数据库操作,我们都可以扩展,没有做不到,只有我们想不到。

步骤一、在mail.php中(生产环境的配置,注意mail-local.php是测试环境才用到的配置)的componets数组中增加:

写道
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'useFileTransport' => false, //这句一定有,false发送邮件,true只是生成邮件在runtime文件夹下,不发邮件
'transport' => [
'class' => 'Swift_SmtpTransport',
'host' => 'smtp.163.com', //每种邮箱的host配置不一样
'username' => 'xxxx',
'password' => 'xxxx',
'port' => '25',
// 'encryption' => 'tls',
],
'messageConfig' => [
'charset' => 'UTF-8',
'from' => ['[email protected]' => '发件人姓名'],
],
],

 步骤二、common中创建目录(就是windows中的文件夹)libs(这个名称是自定义的,也可以叫helper),libs中创建文件Email.php,其内容如下:

<?php
/**
 * 利用Yii自带的swiftmailer发邮件,支持多人发送
 * 可以利用模板发送,也可以发送纯文本或HTML,但只能3选1
 * 优先级为纯文本>HTML>模板发送
 */
namespace common\libs;

class Email {
	public static function sendEmail($option = []) {
		$default = [
			'text' => '',
			'html' => '',
			'tpl' => [
			],
			'subject' => '测试邮件',
			'to' => [
			],
			'attachFiles' => [
			],
		];
		$option = array_merge($default, $option);
		$mail = \Yii::$app->mailer;
		if ($option['text']) {
			$mail = $mail->compose();
			$mail->setTextBody($option['text']);
		} else if ($option['html']) {
			$mail = $mail->compose();
			$mail->setHtmlBody($option['html']);
		} else if ($option['tpl']) {
			$mail = $mail->compose($option['tpl']['file'], $option['tpl']['var']);
		} else {
			return ['code' => 0, 'msg' => '参数有误!'];
		}
		$mail->setSubject($option['subject']);
		foreach ($option['attachFiles'] as $fileAbsPath) {
			$mail->attach($fileAbsPath);
		}
		$mail->setBcc($option['to']); // 密送,批量发送时,收件人看到邮件的收件人只写了自己
		try {
			$res = $mail->send();
			if ($res) {
				return ['code' => 0, 'msg' => '邮件发送成功!'];
			} else {
				var_dump($res);exit;
				return ['code' => -1, 'msg' => '邮件发送失败:' . $mail->error()];
			}
		} catch (Swift_ConnectionException $e) {
			return ['code' => -2, 'msg' => '邮件发送失败:' . $e->getMessage()];
		}

	}
}

 第三步、可以在各种控制器、模型层里调用了。注意一下,MVC模式开发,复杂业务逻辑都应该放到Model层,我这里只是实例而已。在SiteController.php中新增如下Action:

public function actionEmail() {
		\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
		$option = [
			// 'text' => '测试纯文本邮件',
			'html' => '<font color=red>测试HTML</font>',
			'tpl' => [
				'file' => 'email_tpl.html',
				'var' => [
					'name' => '丁华能',
				],
			],
			'subject' => '测试HTML',
			'to' => [
				'[email protected]' => 'dhn',
				// '[email protected]' => 'dhn163',
			],
			'attachFiles' => [
				// \Yii::getAlias('@webroot') . '/uploads/test.docx',
			],
		];
		$res = \common\libs\Email::sendEmail($option);
		return $res;
	}

 

 步骤四、在SiteController.php的上层目录controllers所在的同级目录中创建目录mail/layouts,layouts中创建文件html.php(默认布局,跟main.php如出一辙):

<?php $this->beginPage()?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=<?=Yii::$app->charset?>" />
    <?php $this->head()?>
</head>
<body>
    <?php $this->beginBody()?>
    <?=$content?>
    <div class="footer">丁华能</div>
    <?php $this->endBody()?>
</body>
</html>
<?php $this->endPage()?>

步骤五、在mail中创建email_tpl.html(yii渲染html是可以的,只要在render中带上后缀名):

<style type="text/css">
.red {color: red;}
</style>
<div class="red">
    这是一封来自<?=$name?>的邮件。
</div>

 一切OK,访问相应的网址,就能看到json返回,如果成功,去收件箱看邮件吧,另外,配置的发件人的发件箱也能看到。

注意:bcc在邮件的smtp协议中规定的是密送功能,比如邮件你需要通知到你的所有客户,但这些客户之间毫无联系,那么你不能发一封邮件,让大家都看到一长串的收件人。这就需要用到密送。如果是企业内部,则应该用抄送功能(信件中,所有收件人都能看到)。

 

猜你喜欢

转载自canlynet.iteye.com/blog/2383761
今日推荐