SwitchMailer电子邮件库

许多web应用因为安全原因需要通过电子邮件发送通知和确认客户端动作。Yii2框架为已存在的SwitchMailer库提供了一个wrapper,yiisoft/yii2-swiftmailer

准备

按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。

基础应用和高级应用都包含这个扩展。

如何做…

现在我们将会尝试从我们自己的应用中发送任何种类的电子邮件。

发送纯文本电子邮件

  1. config/console.php文件中设置mailer配置:
  1. 'components' => [
  2. // ...
  3. 'mailer' => [
  4. 'class' => 'yii\swiftmailer\Mailer',
  5. 'useFileTransport' => true,
  6. ],
  7. // ...
  8. ],
  1. 创建一个测试控制台控制器,MailController
  1. <?php
  2. namespace app\commands;
  3. use yii\console\Controller;
  4. use Yii;
  5. class MailController extends Controller
  6. {
  7. public function actionSend()
  8. {
  9. Yii::$app->mailer->compose()
  10. ->setTo('to@yii-book.app')
  11. ->setFrom(['from@yii-book.app' => Yii::$app->name])
  12. ->setSubject('My Test Message')
  13. ->setTextBody('My Text Body')
  14. ->send();
  15. }
  16. }
  1. 运行如下控制台命令:
  1. php yii main/send
  1. 检查你的runtime/mail目录。它应该包含你的邮件文件。

注意:邮件文件包含了特殊电子邮件源格式的信息,兼容任何邮件软件。你可以按纯文本文件打开。

  1. 设置useFileTransport参数为false,或者从配置中移除这个字符串:
  1. 'mailer' => [
  2. 'class' => 'yii\swiftmailer\Mailer',
  3. ],

然后将你真实的电子邮件ID放入setTo()方法:

  1. ->setTo('my@real-email.com')
  1. 再次运行控制台命令:
  1. php yii mail/send
  1. 检查你的inbox目录。

注意:默认情况下,SwiftMailer使用了一个标准的PHP函数,mail(),来发送邮件。请检查你的服务器是否正确设置,从而可以使用mail()函数发送邮件。

需要邮箱系统拒绝没有DKIM和SPF签名的邮件(例如使用mail()函数发送的邮件)或者将他们放到垃圾文件夹中。

发送HTML内容

  1. 检查你应用中的mail/layouts/html.php文件并使用如下内容添加mail/layouts/text.php文件:
  1. <?php
  2. /* @var $this \yii\web\View */
  3. /* @var $message \yii\mail\MessageInterface */
  4. /* @var $content string */
  5. ?>
  6. <?php $this->beginPage() ?>
  7. <?php $this->beginBody() ?>
  8. <?= $content ?>
  9. <?php $this->endBody() ?>
  10. <?php $this->endPage() ?>
  1. mail/message-html.php文件中创建你自己的视图:
  1. <?php
  2. use yii\helpers\Html;
  3. /* @var $this yii\web\View */
  4. /* @var $name string */
  5. ?>
  6. <p>Hello, <?= Html::encode($name) ?>!</p>
  7. Create a mail/message-text.php file with the same content, but without HTML tags:
  8. <?php
  9. use yii\helpers\Html;
  10. /* @var $this yii\web\View */
  11. /* @var $name string */
  12. ?>
  13. Hello, <?= Html::encode($name) ?>!
  1. 使用如下代码创建一个控制台控制器MailController
  1. <?php
  2. namespace app\commands;
  3. use yii\console\Controller;
  4. use Yii;
  5. class MailController extends Controller
  6. {
  7. public function actionSendHtml()
  8. {
  9. $name = 'John';
  10. Yii::$app->mailer->compose('message-html',['name' => $name])
  11. ->setTo('to@yii-book.app')
  12. ->setFrom(['from@yii-book.app' => Yii::$app->name])
  13. ->setSubject('My Test Message')
  14. ->send();
  15. }
  16. public function actionSendCombine()
  17. {
  18. $name = 'John';
  19. Yii::$app->mailer->compose(['html' => 'message-html', 'text' => 'message-text'], ['name' => $name,])
  20. ->setTo('to@yii-book.app')
  21. ->setFrom(['from@yii-book.app'
  22. => Yii::$app->name])
  23. ->setSubject('My Test Message')
  24. ->send();
  25. }
  26. }
  1. 运行如下控制台命令:
  1. php yii mail/send-html
  2. php yii mail/send-combine

使用SMTP传输

  1. mailer组件设置transport参数:
  1. 'mailer' => [
  2. 'class' => 'yii\swiftmailer\Mailer',
  3. 'transport' => [
  4. 'class' => 'Swift_SmtpTransport',
  5. 'host' => 'smtp.gmail.com',
  6. 'username' => 'username@gmail.com',
  7. 'password' => 'password',
  8. 'port' => '587',
  9. 'encryption' => 'tls',
  10. ],
  11. ],
  1. 书写并运行如下代码:
  1. Yii::$app->mailer->compose()
  2. ->setTo('to@yii-book.app')
  3. ->setFrom('username@gmail.com')
  4. ->setSubject('My Test Message')
  5. ->setTextBody('My Text Body')
  6. ->send();
  1. 检查你的Gmail收件箱。

注意:Gmail自动重写From字段为你的默认电子邮件ID,但其他电子邮件系统没有这么做。在传输配置中总是使用一个唯一电子邮件ID,并在setFrom()方法中为其它电子邮件系统中传递反垃圾邮件政策。

添加附件和图片

添加相关的方法来附加任何文件到你的邮件中:

  1. class MailController extends Controller
  2. {
  3. public function actionSendAttach()
  4. {
  5. Yii::$app->mailer->compose()
  6. ->setTo('to@yii-book.app')
  7. ->setFrom(['from@yii-book.app' => Yii::$app->name])
  8. ->setSubject('My Test Message')
  9. ->setTextBody('My Text Body')
  10. ->attach(Yii::getAlias('@app/README.md'))
  11. ->send();
  12. }
  13. }

或者在你的电子邮件视图文件中使用embed()方法来粘贴一个图片到电子邮件内容中:

  1. <img src="<?= $message->embed($imageFile); ?>">

它会自动添加图片文件附件并插入它的唯一标识。

工作原理…

wrapper实现了\yii\mail\MailerInterface。它的compose()方法返回了一个消息对象(\yii\mail\MessageInterface的一个实现)。

你可以使用setTextBody()setHtmlBody()手动设置纯文本和HTML内容,或者你可以将你的视图和视图参数传递给compose()方法。在这个例子中,mailer调用\yii\web\View::render()方法来渲染相应的内容。

useFileTransport参数在文件中存储电子邮件而不是真正的发送。它对于本地开发和应用测试非常有用。

参考