View on GitHub

yii2-cookbook-chinese

Yii Application Development Cookbook(Third Edition)中文翻译

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

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

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

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

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

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

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

发送HTML内容

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

使用SMTP传输

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

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

添加附件和图片

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

class MailController extends Controller
{
    public function actionSendAttach()
    {
        Yii::$app->mailer->compose()
            ->setTo('to@yii-book.app')
            ->setFrom(['from@yii-book.app' => Yii::$app->name])
            ->setSubject('My Test Message')
            ->setTextBody('My Text Body')
            ->attach(Yii::getAlias('@app/README.md'))
            ->send();
    }
}

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

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

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

工作原理…

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

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

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

参考