Laravel 邮件发送与配置

Laravel 提供了简洁而强大的邮件发送功能,基于 Symfony Mailer,支持 SMTP、Mailgun、Postmark、Amazon SES 等多种驱动。通过 Mailable 类和 Markdown 模板,你可以轻松构建美观的邮件内容,并利用队列系统异步发送,提升应用性能。

📧 核心概念: 邮件功能围绕三个核心组件:配置文件(config/mail.php)、Mailable 类(负责构建邮件内容)、以及队列(可选)。本章将逐步带你掌握所有关键环节。

1. 邮件配置

Laravel 的邮件配置位于 config/mail.php.env 文件中。你需要根据使用的邮件服务设置正确的驱动和凭据。

常用驱动配置示例

驱动.env 配置项说明
SMTPMAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@example.com
MAIL_FROM_NAME="${APP_NAME}"
最通用的方式,支持任何 SMTP 服务器。
MailgunMAIL_MAILER=mailgun
MAILGUN_DOMAIN=your-domain.com
MAILGUN_SECRET=your-api-key
MAILGUN_ENDPOINT=api.mailgun.net
需安装 symfony/mailgun-mailer
Amazon SESMAIL_MAILER=ses
SES_KEY=your-aws-key
SES_SECRET=your-aws-secret
SES_REGION=us-east-1
需安装 aws/aws-sdk-php
logMAIL_MAILER=log将邮件写入日志文件(用于开发调试)。
arrayMAIL_MAILER=array将邮件内容保存到数组(用于测试)。

注意: 修改 .env 后需重启 Laravel 开发服务器才能生效。

2. 创建 Mailable 类

使用 Artisan 命令生成 Mailable 类。例如,创建一个用户欢迎邮件:


php artisan make:mail WelcomeMail
                    

生成的类位于 app/Mail/WelcomeMail.php。在 build 方法中配置邮件视图、主题等。

简单示例:


<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class WelcomeMail extends Mailable
{
    use Queueable, SerializesModels;

    public $user; // 公共属性可在视图中直接使用

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function build()
    {
        return $this->from('hello@example.com', 'Example Team')
                    ->subject('欢迎加入我们')
                    ->view('emails.welcome'); // 指定视图
    }
}
                    

视图文件 resources/views/emails/welcome.blade.php


<h1>您好,{{ $user->name }}!</h1>
<p>感谢您注册我们的服务。</p>
                    

3. 发送邮件

使用 Mail Facade 的 to()send() 方法:


use Illuminate\Support\Facades\Mail;
use App\Mail\WelcomeMail;

// 在控制器或其他位置
$user = User::find(1);
Mail::to($user->email)->send(new WelcomeMail($user));
                    

你也可以同时发送给多个收件人:


Mail::to(['email1@example.com', 'email2@example.com'])->send(new WelcomeMail($user));
                    

4. Markdown 邮件

Laravel 提供了基于 Markdown 的邮件模板,自带响应式布局,支持按钮、表格等组件。生成 Markdown Mailable:


php artisan make:mail WelcomeMail --markdown=emails.welcome
                    

生成的 Mailable 中 build 方法会调用 markdown()


public function build()
{
    return $this->from('hello@example.com')
                ->subject('欢迎加入')
                ->markdown('emails.welcome');
}
                    

Markdown 模板示例 (resources/views/emails/welcome.blade.php):


@component('mail::message')
# 欢迎,{{ $user->name }}!

感谢您注册我们的服务。请点击下面的按钮验证您的邮箱:

@component('mail::button', ['url' => $verificationUrl])
验证邮箱
@endcomponent

谢谢,
{{ config('app.name') }} @endcomponent

Laravel 内置了邮件组件(如 mail::message, mail::button, mail::panel, mail::table),可以轻松构建美观的邮件。

5. 队列发送邮件(提升响应速度)

将邮件放入队列可以避免在 HTTP 请求周期内等待邮件发送,提高用户体验。只需让 Mailable 实现 ShouldQueue 接口,或使用 queue() 方法。

方法一:实现 ShouldQueue 接口


use Illuminate\Contracts\Queue\ShouldQueue;

class WelcomeMail extends Mailable implements ShouldQueue
{
    // ...
}
                    

然后正常调用 Mail::to(...)->send(...),邮件会自动推送到队列。

方法二:使用 queue() 方法


Mail::to($user->email)->queue(new WelcomeMail($user));
                    

如果需要延迟发送,可以使用 later()


Mail::to($user->email)->later(now()->addMinutes(10), new WelcomeMail($user));
                    
⚠️ 前置条件: 队列功能需要配置队列驱动(如 redis、database、sqs)并运行队列监听器(php artisan queue:work)。

6. 本地测试邮件

在开发环境中,推荐使用 log 驱动将邮件内容写入日志,或使用 Mailtrap 等服务捕获邮件。你也可以使用 array 驱动配合测试断言。

使用 Mailtrap 的 .env 配置示例:


MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your-mailtrap-username
MAIL_PASSWORD=your-mailtrap-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@example.com
MAIL_FROM_NAME="${APP_NAME}"
                    

7. 添加附件与内嵌图片

添加附件

在 Mailable 的 build 方法中使用 attach()


public function build()
{
    return $this->view('emails.invoice')
                ->attach(storage_path('app/invoices/invoice.pdf'), [
                    'as' => 'invoice.pdf',
                    'mime' => 'application/pdf',
                ]);
}
                    

内嵌图片

使用 embed() 方法将图片嵌入邮件内容,并在视图中通过 cid 引用:


public function build()
{
    return $this->view('emails.welcome')
                ->with([
                    'logo' => $this->embed(storage_path('app/public/logo.png'))
                ]);
}
                    

视图中使用:<img src="{{ $logo }}">

8. 常见问题与解决方案

  • 邮件发送超时或失败: 检查网络连接、SMTP 配置是否正确,或尝试使用队列减少超时影响。
  • Gmail 需要应用专用密码: 如果开启了两步验证,请在 Google 账户安全设置中生成“应用专用密码”。
  • Markdown 邮件样式不生效: 确保已发布邮件主题(php artisan vendor:publish --tag=laravel-mail),并检查视图路径。
  • 队列邮件未发送: 确保队列工作器正在运行(php artisan queue:work),且队列驱动配置正确。
  • 本地测试看不到邮件: 使用 log 驱动查看 storage/logs/laravel.log 文件。

9. 总结

Laravel 的邮件系统设计得既灵活又易于使用。通过配置驱动、创建 Mailable 类、使用 Markdown 模板以及队列功能,你可以轻松实现从简单通知到复杂营销邮件的需求。建议在生产环境中使用专业的邮件服务(如 Mailgun、SES),并始终将邮件发送任务放入队列,以提升应用性能。

📖 扩展阅读: 官方文档 MailQueues 章节提供了更深入的配置和高级用法。