Skip to content

邮件

介绍

Laravel 提供了一个简洁、简单的 API,基于流行的 SwiftMailer 库。Laravel 提供了 SMTP、Mailgun、Mandrill、Amazon SES、PHP 的 mail 函数和 sendmail 的驱动程序,允许您快速开始通过本地或云服务发送邮件。

驱动程序先决条件

基于 API 的驱动程序如 Mailgun 和 Mandrill 通常比 SMTP 服务器更简单、更快。所有 API 驱动程序都要求您的应用程序安装 Guzzle HTTP 库。您可以通过在 composer.json 文件中添加以下行来安装 Guzzle:

php
"guzzlehttp/guzzle": "~5.3|~6.0"

Mailgun 驱动程序

要使用 Mailgun 驱动程序,首先安装 Guzzle,然后在 config/mail.php 配置文件中将 driver 选项设置为 mailgun。接下来,验证您的 config/services.php 配置文件包含以下选项:

php
'mailgun' => [
    'domain' => 'your-mailgun-domain',
    'secret' => 'your-mailgun-key',
],

Mandrill 驱动程序

要使用 Mandrill 驱动程序,首先安装 Guzzle,然后在 config/mail.php 配置文件中将 driver 选项设置为 mandrill。接下来,验证您的 config/services.php 配置文件包含以下选项:

php
'mandrill' => [
    'secret' => 'your-mandrill-key',
],

SES 驱动程序

要使用 Amazon SES 驱动程序,安装 Amazon AWS SDK for PHP。您可以通过在 composer.json 文件的 require 部分添加以下行来安装此库:

php
"aws/aws-sdk-php": "~3.0"

接下来,在 config/mail.php 配置文件中将 driver 选项设置为 ses。然后,验证您的 config/services.php 配置文件包含以下选项:

php
'ses' => [
    'key' => 'your-ses-key',
    'secret' => 'your-ses-secret',
    'region' => 'ses-region',  // 例如 us-east-1
],

发送邮件

Laravel 允许您将电子邮件消息存储在 视图 中。例如,为了组织您的电子邮件,您可以在 resources/views 目录中创建一个 emails 目录:

要发送消息,请使用 Mail facade 上的 send 方法。send 方法接受三个参数。首先是包含电子邮件消息的 视图 的名称。其次是您希望传递给视图的数据数组。最后是一个接收消息实例的 Closure 回调,允许您自定义收件人、主题和邮件消息的其他方面:

php
<?php

namespace App\Http\Controllers;

use Mail;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * 向用户发送电子邮件提醒。
     *
     * @param  Request  $request
     * @param  int  $id
     * @return Response
     */
    public function sendEmailReminder(Request $request, $id)
    {
        $user = User::findOrFail($id);

        Mail::send('emails.reminder', ['user' => $user], function ($m) use ($user) {
            $m->from('hello@app.com', 'Your Application');

            $m->to($user->email, $user->name)->subject('Your Reminder!');
        });
    }
}

由于我们在上面的示例中传递了一个包含 user 键的数组,我们可以使用以下 PHP 代码在我们的电子邮件视图中显示用户的名称:

php
<?php echo $user->name; ?>
lightbulb

一个 $message 变量总是被传递给电子邮件视图,并允许 内嵌附件。因此,您应该避免在视图负载中传递 message 变量。

构建消息

如前所述,传递给 send 方法的第三个参数是一个 Closure,允许您在电子邮件消息本身上指定各种选项。使用此闭包,您可以指定消息的其他属性,例如抄送、密件抄送等:

php
Mail::send('emails.welcome', $data, function ($message) {
    $message->from('us@example.com', 'Laravel');

    $message->to('foo@example.com')->cc('bar@example.com');
});

以下是 $message 消息构建器实例上可用的方法列表:

php
$message->from($address, $name = null);
$message->sender($address, $name = null);
$message->to($address, $name = null);
$message->cc($address, $name = null);
$message->bcc($address, $name = null);
$message->replyTo($address, $name = null);
$message->subject($subject);
$message->priority($level);
$message->attach($pathToFile, array $options = []);

// 从原始 $data 字符串附加文件...
$message->attachData($data, $name, array $options = []);

// 获取底层的 SwiftMailer 消息实例...
$message->getSwiftMessage();
lightbulb

传递给 Mail::send 闭包的消息实例扩展了 SwiftMailer 消息类,允许您调用该类上的任何方法来构建您的电子邮件消息。

发送纯文本邮件

默认情况下,传递给 send 方法的视图被假定为包含 HTML。然而,通过将数组作为第一个参数传递给 send 方法,您可以指定一个纯文本视图以便与 HTML 视图一起发送:

php
Mail::send(['html.view', 'text.view'], $data, $callback);

或者,如果您只需要发送纯文本电子邮件,您可以使用数组中的 text 键来指定:

php
Mail::send(['text' => 'view'], $data, $callback);

发送原始字符串

如果您希望直接发送原始字符串,可以使用 raw 方法:

php
Mail::raw('Text to e-mail', function ($message) {
    //
});

附件

要向电子邮件添加附件,请在传递给您的闭包的 $message 对象上使用 attach 方法。attach 方法接受文件的完整路径作为第一个参数:

php
Mail::send('emails.welcome', $data, function ($message) {
    //

    $message->attach($pathToFile);
});

在将文件附加到消息时,您还可以通过将 array 作为第二个参数传递给 attach 方法来指定显示名称和/或 MIME 类型:

php
$message->attach($pathToFile, ['as' => $display, 'mime' => $mime]);

内嵌附件

在电子邮件视图中嵌入图像

将内嵌图像嵌入到电子邮件中通常很麻烦;然而,Laravel 提供了一种方便的方法来将图像附加到您的电子邮件中并检索适当的 CID。要嵌入内嵌图像,请在您的电子邮件视图中使用 $message 变量上的 embed 方法。请记住,Laravel 会自动将 $message 变量提供给您的所有电子邮件视图:

php
<body>
    这里是一张图片:

    <img src="<?php echo $message->embed($pathToFile); ?>">
</body>

在电子邮件视图中嵌入原始数据

如果您已经有一个希望嵌入到电子邮件消息中的原始数据字符串,可以在 $message 变量上使用 embedData 方法:

php
<body>
    这里是来自原始数据的图片:

    <img src="<?php echo $message->embedData($data, $name); ?>">
</body>

队列邮件

队列邮件消息

由于发送电子邮件消息可能会显著延长应用程序的响应时间,许多开发人员选择将电子邮件消息排队以便后台发送。Laravel 使用其内置的 统一队列 API 使这变得简单。要将邮件消息排队,请在 Mail facade 上使用 queue 方法:

php
Mail::queue('emails.welcome', $data, function ($message) {
    //
});

此方法将自动处理将作业推送到队列以在后台发送邮件消息。当然,您需要在使用此功能之前 配置您的队列

延迟消息队列

如果您希望延迟队列电子邮件消息的发送,可以使用 later 方法。要开始,只需将您希望延迟发送消息的秒数作为方法的第一个参数传递:

php
Mail::later(5, 'emails.welcome', $data, function ($message) {
    //
});

推送到特定队列

如果您希望指定要将消息推送到的特定队列,可以使用 queueOnlaterOn 方法:

php
Mail::queueOn('queue-name', 'emails.welcome', $data, function ($message) {
    //
});

Mail::laterOn('queue-name', 5, 'emails.welcome', $data, function ($message) {
    //
});

邮件与本地开发

在开发发送电子邮件的应用程序时,您可能不希望实际将电子邮件发送到真实的电子邮件地址。Laravel 提供了几种方法来“禁用”实际发送电子邮件消息。

日志驱动程序

一种解决方案是在本地开发期间使用 log 邮件驱动程序。此驱动程序将所有电子邮件消息写入您的日志文件以供检查。有关按环境配置应用程序的更多信息,请查看 配置文档

通用收件人

Laravel 提供的另一种解决方案是设置一个通用收件人来接收框架发送的所有电子邮件。这样,您的应用程序生成的所有电子邮件将发送到一个特定的地址,而不是发送到实际指定的地址。这可以通过在 config/mail.php 配置文件中设置 to 选项来完成:

php
'to' => [
    'address' => 'dev@domain.com',
    'name' => 'Dev Example'
],

Mailtrap

最后,您可以使用像 Mailtrap 这样的服务和 smtp 驱动程序将您的电子邮件消息发送到一个“虚拟”邮箱,您可以在真实的电子邮件客户端中查看它们。这种方法的好处是允许您在 Mailtrap 的消息查看器中实际检查最终的电子邮件。

事件

Laravel 在发送邮件消息之前会触发 mailer.sending 事件。请记住,此事件是在邮件发送时触发的,而不是在邮件排队时。您可以在 EventServiceProvider 中注册事件监听器:

php
/**
 * 为您的应用程序注册任何其他事件。
 *
 * @param  \Illuminate\Contracts\Events\Dispatcher  $events
 * @return void
 */
public function boot(DispatcherContract $events)
{
    parent::boot($events);

    $events->listen('mailer.sending', function ($message) {
        //
    });
}