5 关注者

邮件

注意:本节内容正在开发中。

Yii 支持邮件的创建和发送。但是,框架核心只提供内容创建功能和基本接口。实际的邮件发送机制应该由扩展提供,因为不同的项目可能需要不同的实现,并且它通常依赖于外部服务和库。

对于大多数常见情况,您可以使用 yii2-symfonymailer 官方扩展。

配置

邮件组件的配置取决于您选择的扩展。一般来说,您的应用程序配置应该如下所示

return [
    //....
    'components' => [
        'mailer' => [
            'class' => 'yii\symfonymailer\Mailer',
            'useFileTransport' => false,
            'transport' => [
                'dsn' => 'smtp://user:[email protected]:465',
            ],
        ],
    ],
];

基本用法

一旦 mailer 组件配置完成,您可以使用以下代码发送邮件:

Yii::$app->mailer->compose()
    ->setFrom('[email protected]')
    ->setTo('[email protected]')
    ->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('[email protected]');
} else {
    $message->setFrom(Yii::$app->user->identity->email);
}
$message->setTo(Yii::$app->params['adminEmail'])
    ->setSubject('Message subject')
    ->setTextBody('Plain text content')
    ->send();

注意:每个 mailer 扩展都包含两个主要类:MailerMessageMailer 始终知道 Message 的类名和特性。不要尝试直接实例化 Message 对象——始终使用 compose() 方法来创建它。

您也可以一次发送多封邮件:

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

某些特定的邮件扩展可能会从这种方法中受益,例如使用单个网络消息等。

撰写邮件内容

Yii 允许通过特殊的视图文件来创建邮件内容。默认情况下,这些文件应位于 @app/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')) ?>

为了通过视图文件创建邮件内容,只需将视图名称传递给 compose() 方法即可:

Yii::$app->mailer->compose('home-link') // a view rendering result becomes the message body here
    ->setFrom('[email protected]')
    ->setTo('[email protected]')
    ->setSubject('Message subject')
    ->send();

您可以将其他视图参数传递给 compose() 方法,这些参数将在视图文件内部可用:

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

您可以为 HTML 和纯文本邮件内容指定不同的视图文件:

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

如果您将视图名称指定为标量字符串,则其渲染结果将用作 HTML 正文,而纯文本正文将通过从 HTML 正文中删除所有 HTML 实体来创建。

视图渲染结果可以包装在布局中,可以通过 yii\mail\BaseMailer::$htmlLayoutyii\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();

// attach file from local file system
$message->attach('/path/to/source/file.pdf');

// create attachment on-the-fly
$message->attachContent('Attachment content', ['fileName' => 'attach.txt', 'contentType' => 'text/plain']);

嵌入图像

您可以使用embed()方法将图像嵌入邮件内容中。此方法返回附件 ID,然后应在img标签中使用。当通过视图文件撰写邮件内容时,此方法易于使用。

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

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

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

测试和调试

开发人员通常需要检查应用程序实际发送的邮件、邮件内容等。Yii 通过yii\mail\BaseMailer::useFileTransport提供了此功能。如果启用,此选项会强制将邮件数据保存到本地文件,而不是常规发送。这些文件将保存在yii\mail\BaseMailer::fileTransportPath下,默认情况下为@runtime/mail

注意:您可以将邮件保存到文件或发送给实际收件人,但不能同时执行这两项操作。

邮件文件可以使用普通的文本文件编辑器打开,因此您可以浏览实际的邮件头、内容等。此机制在调试应用程序或运行单元测试时可能很有用。

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

创建您自己的邮件解决方案

为了创建您自己的自定义邮件解决方案,您需要创建两个类:一个用于Mailer,另一个用于Message。您可以使用yii\mail\BaseMaileryii\mail\BaseMessage作为解决方案的基础类。这些类已经包含了本指南中描述的基本逻辑。但是,它们的用法不是强制性的,只需实现yii\mail\MailerInterfaceyii\mail\MessageInterface接口即可。然后,您需要实现所有抽象方法来构建您的解决方案。

发现错别字或您认为此页面需要改进?
在 github 上编辑它 !