邮件
介绍
Laravel 提供了一个简洁、简单的 API,基于流行的 SwiftMailer 库。Laravel 提供了 SMTP、Mailgun、Mandrill、SparkPost、Amazon SES、PHP 的 mail
函数和 sendmail
的驱动程序,允许您快速开始通过本地或云服务发送邮件。
驱动程序先决条件
基于 API 的驱动程序如 Mailgun 和 Mandrill 通常比 SMTP 服务器更简单、更快。所有 API 驱动程序都要求为您的应用程序安装 Guzzle HTTP 库。您可以通过在 composer.json
文件中添加以下行来安装 Guzzle:
"guzzlehttp/guzzle": "~5.3|~6.0"
Mailgun 驱动程序
要使用 Mailgun 驱动程序,首先安装 Guzzle,然后在 config/mail.php
配置文件中将 driver
选项设置为 mailgun
。接下来,验证您的 config/services.php
配置文件包含以下选项:
'mailgun' => [
'domain' => 'your-mailgun-domain',
'secret' => 'your-mailgun-key',
],
Mandrill 驱动程序
要使用 Mandrill 驱动程序,首先安装 Guzzle,然后在 config/mail.php
配置文件中将 driver
选项设置为 mandrill
。接下来,验证您的 config/services.php
配置文件包含以下选项:
'mandrill' => [
'secret' => 'your-mandrill-key',
],
SparkPost 驱动程序
要使用 SparkPost 驱动程序,首先安装 Guzzle,然后在 config/mail.php
配置文件中将 driver
选项设置为 sparkpost
。接下来,验证您的 config/services.php
配置文件包含以下选项:
'sparkpost' => [
'secret' => 'your-sparkpost-key',
],
SES 驱动程序
要使用 Amazon SES 驱动程序,安装 Amazon AWS SDK for PHP。您可以通过在 composer.json
文件的 require
部分添加以下行来安装此库:
"aws/aws-sdk-php": "~3.0"
接下来,在 config/mail.php
配置文件中将 driver
选项设置为 ses
。然后,验证您的 config/services.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
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 echo $user->name; ?>
一个 $message
变量总是被传递给电子邮件视图,并允许 内嵌附件的嵌入。因此,您应该避免在视图负载中传递 message
变量。
构建消息
如前所述,传递给 send
方法的第三个参数是一个 Closure
,允许您在电子邮件消息本身上指定各种选项。使用此闭包,您可以指定消息的其他属性,例如抄送、密件抄送等:
Mail::send('emails.welcome', $data, function ($message) {
$message->from('us@example.com', 'Laravel');
$message->to('foo@example.com')->cc('bar@example.com');
});
以下是 $message
消息构建器实例上可用的方法列表:
$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();
传递给 Mail::send
闭包的消息实例扩展了 SwiftMailer 消息类,允许您调用该类上的任何方法来构建您的电子邮件消息。
发送纯文本邮件
默认情况下,传递给 send
方法的视图被假定为包含 HTML。然而,通过将数组作为第一个参数传递给 send
方法,您可以指定一个纯文本视图以便与 HTML 视图一起发送:
Mail::send(['html.view', 'text.view'], $data, $callback);
或者,如果您只需要发送纯文本电子邮件,您可以在数组中使用 text
键来指定:
Mail::send(['text' => 'view'], $data, $callback);
发送原始字符串
如果您希望直接发送原始字符串,可以使用 raw
方法:
Mail::raw('Text to e-mail', function ($message) {
//
});
附件
要向电子邮件添加附件,请在传递给您的闭包的 $message
对象上使用 attach
方法。attach
方法接受文件的完整路径作为第一个参数:
Mail::send('emails.welcome', $data, function ($message) {
//
$message->attach($pathToFile);
});
在将文件附加到消息时,您还可以通过将 array
作为第二个参数传递给 attach
方法来指定显示名称和/或 MIME 类型:
$message->attach($pathToFile, ['as' => $display, 'mime' => $mime]);
attachData
方法可用于将原始字节字符串作为附件附加。例如,如果您在内存中生成了一个 PDF 并希望将其附加到电子邮件而不将其写入磁盘,可以使用此方法:
$message->attachData($pdf, 'invoice.pdf');
$message->attachData($pdf, 'invoice.pdf', ['mime' => $mime]);
内嵌附件
在电子邮件视图中嵌入图像
将内嵌图像嵌入到电子邮件中通常很麻烦;然而,Laravel 提供了一种方便的方法来将图像附加到电子邮件并检索适当的 CID。要嵌入内嵌图像,请在电子邮件视图中的 $message
变量上使用 embed
方法。请记住,Laravel 会自动将 $message
变量提供给所有电子邮件视图:
<body>
这里是一张图片:
<img src="<?php echo $message->embed($pathToFile); ?>">
</body>
在电子邮件视图中嵌入原始数据
如果您已经有一个希望嵌入到电子邮件消息中的原始数据字符串,可以在 $message
变量上使用 embedData
方法:
<body>
这里是来自原始数据的图片:
<img src="<?php echo $message->embedData($data, $name); ?>">
</body>
队列邮件
队列邮件消息
由于发送电子邮件消息可能会显著延长应用程序的响应时间,许多开发人员选择将电子邮件消息排队以便后台发送。Laravel 使用其内置的 统一队列 API 使这变得简单。要将邮件消息排队,请在 Mail
facade 上使用 queue
方法:
Mail::queue('emails.welcome', $data, function ($message) {
//
});
此方法将自动处理将作业推送到队列以在后台发送邮件消息。当然,您需要在使用此功能之前 配置您的队列。
延迟消息队列
如果您希望延迟队列电子邮件消息的发送,可以使用 later
方法。要开始,只需将您希望延迟发送消息的秒数作为第一个参数传递给该方法:
Mail::later(5, 'emails.welcome', $data, function ($message) {
//
});
推送到特定队列
如果您希望指定要将消息推送到的特定队列,可以使用 queueOn
和 laterOn
方法:
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
选项来完成:
'to' => [
'address' => 'dev@domain.com',
'name' => 'Dev Example'
],
Mailtrap
最后,您可以使用像 Mailtrap 这样的服务和 smtp
驱动程序将您的电子邮件消息发送到一个“虚拟”邮箱,您可以在真实的电子邮件客户端中查看它们。这种方法的好处是允许您在 Mailtrap 的消息查看器中实际检查最终的电子邮件。
事件
Laravel 在发送邮件消息之前会触发一个事件。请记住,此事件是在邮件发送时触发的,而不是在邮件排队时。您可以在 EventServiceProvider
中注册一个事件监听器:
/**
* 应用程序的事件监听器映射。
*
* @var array
*/
protected $listen = [
'Illuminate\Mail\Events\MessageSending' => [
'App\Listeners\LogSentMessage',
],
];