T-DOC
  • Laravel-11
  • Laravel-10
  • Laravel-6X
  • Laravel-5.5
Dcat-Admin
  • Yii2
  • 重构2
  • Laravel-11
  • Laravel-10
  • Laravel-6X
  • Laravel-5.5
Dcat-Admin
  • Yii2
  • 重构2
  • 前言

    • 关于 Yii
    • 从 Yii 1.1 升级
    • Yii 2.0 升级说明
    • 贡献者指引
    • 捐献和赞助
  • 版本管理

    • 发行说明
    • 版本说明
    • 更新记录
  • 快速入门

    • 安装 Yii
    • 目录结构
    • 部署
    • Hello world
    • 使用表单
    • 使用数据库
    • 使用 Gii 生成代码
    • 编辑器与 IDE
  • 核心架构

    • 请求生命周期
    • 单一入口
    • 应用主体
    • 组件
    • 属性
    • 事件
    • 行为
    • 配置
    • 别名
    • 类自动加载
    • 服务定位器
    • 依赖注入容器
  • 高级应用模板

    • 安装
    • 框架结构
    • 运行测试
    • 环境与配置
    • 自定义应用模板
  • 基础功能

    • 路由
    • 控制器
    • 过滤器
    • 请求
    • 响应
    • 模型
    • 视图
    • 模块
    • 小部件
    • 前端资源
    • 扩展
    • Sessions 和 Cookies
    • 错误处理
    • 日志
  • 数据库

    • 数据库访问对象(DAO)
    • 查询构造器
    • 活动记录
    • 数据库迁移
    • Redis
    • Sphinx
    • Elasticsearch
    • MongoDB
  • 安全

    • 认证
    • 授权
    • 加密
    • Email 认证
    • 验证码
    • 社会化登录
    • 密码
  • 进阶功能

    • 缓存
    • 发送邮件
    • HTTP 客户端
    • 国际化
    • 队列
    • 控制台应用
    • 助手类
    • 验证器
  • RESTful Web 服务

    • 快速入门
    • 资源
    • 控制器
    • 路由
    • 格式化响应
    • 认证
    • 速率限制(限流)
    • 版本化
    • 错误处理
  • 开发工具

    • 调试工具栏和调试器
    • 使用 Gii 生成代码

发送邮件

Yii 支持电子邮件信息的合成和发送。然而,框架核心只提供内容组合功能和基本接口。实际的邮件发送机制应该由扩展提供,因为不同的项目可能需要不同的实现,它通常依赖于外部服务和库。

对于最常见的情况,你可以使用 yii2-swiftmailer 官方扩展,一般在 Yii2 框架应用模板安装后就自动安装了这个扩展。

当然你可以使用 yii2-symfonymailer 官方扩展。这个扩展为 Yii 框架 2.0 提供了一个 Symfony Mailer 邮件解决方案,在本文后面的内容中,都将介绍。

配置

邮件组件配置取决于您所选择的扩展。一般来说,你的应用程序配置应该是这样的:

return [
    //....
    'components' => [
        'mailer' => [
            'class' => 'yii\swiftmailer\Mailer',
            // 包含用于撰写邮件消息的视图文件的目录,默认值是 '@app/mail'
            'viewPath' => '@common/mail',
            // 'useFileTransport' => true,
            // 'useFileTransport' 的默认值为 true,即将所有邮件发送到一个文件。你必须将它设置为 false,并为邮件发送者配置一个传输来发送真实的邮件。
            'useFileTransport' => false,
            // 当 'useFileTransport' 为 false 时,才配置。
            'transport' => [
                'class' => 'Swift_SmtpTransport',
                'encryption' => 'tls',
                'host' => 'your_mail_server_host',
                'port' => 'your_smtp_port',
                'username' => 'your_username',
                'password' => 'your_password',
            ],
        ],
    ],
];

你也可以跳过 transport 属性的配置。在这种情况下,默认的 \Swift_SendmailTransport 传输将被用于发送电子邮件。

你在配置中使用 ‘constructArgs’ 键,来指定传输构造函数参数。您还可以指定插件列表,这些插件应该使用 ‘plugins’ 键,来注册到传输。例如:

'transport' => [
    'class' => 'Swift_SmtpTransport',
    'constructArgs' => ['localhost', 25],
    'plugins' => [
        [
            'class' => 'Swift_Plugins_ThrottlerPlugin',
            'constructArgs' => [20],
        ],
    ],
],

基本用法

一旦 mailer 组件被配置,你就可以使用下面的代码来发送电子邮件消息:

Yii::$app->mailer->compose()
    ->setFrom('from@domain.com')
    ->setTo('to@domain.com')
    ->setSubject('Message subject')
    ->setTextBody('Plain text content')
    ->setHtmlBody('<b>HTML content</b>')
    ->send();

在上面的例子中,compose() 方法创建了一个邮件消息的实例,然后填充并发送该邮件消息。如果需要,你可以在这个过程中加入更复杂的逻辑,例如:

$message = Yii::$app->mailer->compose();

// 游客
if (Yii::$app->user->isGuest) {
    $message->setFrom('from@domain.com');
} else {
    $message->setFrom(Yii::$app->user->identity->email);
}

$message->setTo(Yii::$app->params['adminEmail'])
    ->setSubject('Message subject')
    ->setTextBody('Plain text content')
    ->send();

:information_source: 注意:每个 mailer 扩展有两大类:Mailer 和 Message。前者总是知道后者的类名和具体内容。不要尝试直接实例化 Message 对象,而是一如既往地使用 compose() 方法接口。

批量发送邮件

你也可以一次同时发送多条邮件消息:

$messages = [];
foreach ($users as $user) {
    $messages[] = Yii::$app->mailer->compose()
        // ...
        ->setTo($user->email);
}

Yii::$app->mailer->sendMultiple($messages);

一些特定的邮件扩展可以从这种方法中受益,比如,使用单一的网络消息等。

撰写邮件内容

Yii 允许你通过一些特殊的视图文件,来组合实际的邮件消息内容。默认情况下,这些文件应该位于 @app/mail 路径下,高级模板一般位于 @common/mail 下。邮件视图文件内容的示例如下:

<?php
use yii\helpers\Html;
use yii\helpers\Url;

/* @var $this \yii\web\View view component instance */
/* @var $message \yii\mail\BaseMessage instance of newly created mail message */

?>
<h2>This message allows you to visit our site home page by one click</h2>
<?= Html::a('Go to home page', Url::home('http')) ?>

In order to compose message content via view file simply pass view name to the compose() method:

Yii::$app->mailer->compose('home-link') // a view rendering result becomes the message body here
    ->setFrom('from@domain.com')
    ->setTo('to@domain.com')
    ->setSubject('Message subject')
    ->send();

You may pass additional view parameters to compose() method, which will be available inside the view files:

Yii::$app->mailer->compose('greetings', [
    'user' => Yii::$app->user->identity,
    'advertisement' => $adContent,
]);

You can specify different view files for HTML and plain text message contents:

Yii::$app->mailer->compose([
    'html' => 'contact-html',
    'text' => 'contact-text',
]);

如果你将视图名指定为一个标量字符串,它的呈现结果将被用作 HTML 主体,而纯文本主体将通过从 HTML 中删除所有的 HTML 实体来组成。

视图渲染结果可以包装到布局(layout)中,可以使用 yii\mail\BaseMailer::htmlLayout 和 yii\mail\BaseMailer::textLayout 来设置。它的工作方式与常规 web 应用中的布局相同。布局可以用来设置邮件 CSS 样式或其他共享内容,示例如下:

<?php
use yii\helpers\Html;

/* @var $this \yii\web\View view component instance */
/* @var $message \yii\mail\MessageInterface the message being composed */
/* @var $content string main view render result */
?>
<?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 ?>" />
    <style type="text/css">
        .heading {...}
        .list {...}
        .footer {...}
    </style>
    <?php $this->head() ?>
</head>
<body>
    <?php $this->beginBody() ?>
    <?= $content ?>
    <div class="footer">With kind regards, <?= Yii::$app->name ?> team</div>
    <?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>

文件附件

您可以使用方法 attach() 和 attachContent() 向邮件消息中添加附件,示例如下:

$message = Yii::$app->mailer->compose();

// 从本地文件系统附加文件
$message->attach('/path/to/source/file.pdf');

// 动态创建附件
$message->attachContent('Attachment content', ['fileName' => 'attach.txt', 'contentType' => 'text/plain']);

插入图片

你可以使用 embed() 方法将图像嵌入到邮件消息内容中。此方法返回附件 ID,然后在 img 标签中使用该 ID。当通过视图文件编写消息内容时,这个方法很容易使用,示例如下:

Yii::$app->mailer->compose('embed-email', ['imageFileName' => '/path/to/image.jpg'])
    // ...
    ->send();

然后在邮件视图文件中,你可以使用以下代码:

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

测试与调试

开发人员经常需要检查应用程序发送了哪些邮件,邮件内容是什么等等。这种能力由 Yii 通过 yii\mail\BaseMailer::useFileTransport 属性授予。如果这个属性为 true,此选项强制将邮件消息数据保存到本地文件中,而不是常规发送。这些文件将保存在 yii\mail\BaseMailer::fileTransportPath 属性值表示的路径下,默认为 @runtime/mail。

注意:您可以将消息保存到文件中,也可以将它们发送到实际的收件人,但不能同时做这两件事。

邮件消息文件可以由常规文本文件编辑器打开,这样您就可以浏览实际的消息头、内容等。在调试应用程序或运行单元测试时,可以证明这种机制本身。

注意:邮件消息文件内容是通过 \yii\mail\MessageInterface::toString() 组成的,所以它取决于你在应用程序中使用的实际邮件扩展名。

Symfony Mailer 扩展

这个扩展为 Yii 框架 2.0 提供了一个 Symfony Mailer 邮件解决方案。

安装

安装此扩展的首选方式是通过 composer,命令如下:

composer require yiisoft/yii2-symfonymailer

或者在您的 composer.json 文件中的 require 部分增加以下内容:

"yiisoft/yii2-symfonymailer": "~2.0.0"

然后执行 composer install 命令即可。

用法

要使用这个扩展,只需在您的应用程序配置中添加以下代码:

return [
    //....
    'components' => [
        'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class,
            'transport' => [
                'scheme' => 'smtps',
                'host' => '',
                'username' => '',
                'password' => '',
                'port' => 465,
                'dsn' => 'native://default',
            ],
            'viewPath' => '@common/mail',
            // send all mails to a file by default. You have to set
            // 'useFileTransport' to false and configure transport
            // for the mailer to send real emails.
            'useFileTransport' => false,
        ],
    ],
];

或者:

return [
    //....
    'components' => [
        'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class,
            'transport' => [
                'dsn' => 'smtp://user:pass@smtp.example.com:25',
            ],
        ],
    ],
];

然后你可以发送电子邮件,示例如下:

Yii::$app->mailer->compose('contact/html')
     ->setFrom('from@domain.com')
     ->setTo($form->email)
     ->setSubject($form->subject)
     ->send();

自定义邮件解决方案

为了创建您自己的自定义邮件解决方案,您需要创建两个类:一个用于 Mailer,另一个用于 Message。您可以使用 yii\mail\BaseMailer 和 yii\mail\BaseMessage 作为你的解决方案的基类。这些类已经包含了本文档中描述的基本逻辑。但是,它们的使用不是强制性的,只要实现 yii\mail\MailerInterface 和 yii\mail\MessageInterface 接口就足够了。然后,您需要实现所有抽象方法来构建您的解决方案。示例如下:

namespace common\components;

use yii\mail\BaseMailer;

class CustomMailer extends BaseMailer
{
    //...
}
namespace common\components;

use yii\mail\BaseMessage;

class CustomMessage extends BaseMessage
{
    //...
}

或者:

namespace common\components;

use yii\base\Component;
use yii\mail\MailerInterface;
use yii\base\ViewContextInterface;

class CustomMailer extends Component implements MailerInterface, ViewContextInterface
{
    //...
}
namespace common\components;

use yii\base\BaseObject;
use yii\mail\MessageInterface;

class CustomMessage extends BaseObject implements MessageInterface
{
    //...
}

💖喜欢本文档的,欢迎点赞、收藏、留言或转发,谢谢支持!
作者邮箱:zhuzixian520@126.com,github地址:github.com/zhuzixian520

Last Updated:
Contributors: Hans
Prev
缓存
Next
HTTP 客户端