Laravel 邮件详解

Laravel邮件支持:illuminate/mail(https://github.com/illuminate/mail)
查看composer.json:

    "require": {
        "php": ">=7.0",
        "erusev/parsedown": "~1.7",
        "illuminate/container": "5.5.*",
        "illuminate/contracts": "5.5.*",
        "illuminate/support": "5.5.*",
        "psr/log": "~1.0",
        "swiftmailer/swiftmailer": "~6.0",
        "tijsverkoyen/css-to-inline-styles": "~2.2"
    },

基于swiftmailer/swiftmailer。illuminate/mail中的MailServiceProvider是defer的。框架在config/app.php中加载这个服务提供者(Illuminate\Mail\MailServiceProvider::class)。

邮件发送需要通过邮局(理论上,直接投递也可以),驱动就是这里的邮局,在内部就叫Transport。基于API驱动的Transport,与邮局的概念本质上是相同的,它只是通过API接受邮件,然后其内部可能再进行分发到其它服务器,然后再把邮件进行投递(普通的邮局也类似,比如SMTP服务器)。

API驱动的Transport:

# API驱动,需要安装guzzlehttp/guzzle
composer require guzzlehttp/guzzle

#Mailgun
#config/mail.php 中设置 driver 选项为 mailgun
#config/services.php 包含
'mailgun' => [
    'domain' => 'your-mailgun-domain',
    'secret' => 'your-mailgun-key',
],

#SparkPost
#config/mail.php 中设置 driver 选项为 SparkPost
#config/services.php 包含
'sparkpost' => [
    'secret' => 'your-sparkpost-key',
],


#SparkPost
#首先安装SDK
composer require aws/aws-sdk-php

#config/mail.php 中设置 driver 选项为 ses
#config/services.php 包含
'ses' => [
    'key' => 'your-ses-key',
    'secret' => 'your-ses-secret',
    'region' => 'ses-region',  // e.g. us-east-1
],

非API驱动:

# smtp 配置较复杂,可以通过.env配置传递参数到config/mail.php,如下一个阿里云邮箱配置
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mxhichina.com
# 安全连接对应465
MAIL_PORT=25 
MAIL_USERNAME=xxx@xx.com
MAIL_PASSWORD=xxxxxxxxx
# 安全连接端口对应465,加密对应ssl
MAIL_ENCRYPTION=null

# log 邮件发送到日志

邮件设置好,接下来就是如果编写一个邮件类,然后把这个邮件类发送出去,可见,这个邮件类主要负责怎么产生内容,发送器把这些内容投递到邮局。

生成编写邮件类:

php artisan make:mail MailTest

<?php

namespace App\Mail;

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

class MailTest extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->from('example@example.com')
        ->view('emails.mail.text');
    }
}

在build()中完成邮件的构建。如果整个系统的邮件都是使用同一个地址发送的,可以config/mail.php中设置’from’ => [‘address’ => ‘example@example.com’, ‘name’ => ‘App Name’],这样如果没有指定发件人,就使用这个设置(默认)。使用view来取到邮件模板,用text来取到纯文本模板(全部看做是纯文本,哪怕其包含html内容)。

在邮件模板中,邮件类的公共属性,模板中可以直接使用。 也可以通过with来传递变量到模板。

    public function build()
    {
        return $this->view('emails.orders.shipped')
            ->with([
                'orderName' => $this->order->name,
                'orderPrice' => $this->order->price,
            ]);
    }

添加数据

# 附件
public function build()
{
    return $this->view('emails.orders.shipped')
        ->attach('/path/to/file');
}
# 附件第二参数
public function build()
{
    return $this->view('emails.orders.shipped')
        ->attach('/path/to/file', [
            'as' => 'name.pdf',
            'mime' => 'application/pdf',
        ]);
}
#原生数据附件 传递字节流
public function build()
{
    return $this->view('emails.orders.shipped')
        ->attachData($this->pdf, 'name.pdf', [
            'mime' => 'application/pdf',
        ]);
}
#内联附件
#嵌套内联图片到邮件中通常是很重的,
#Laravel 提供了便捷的方式附加图片到邮件并获取相应的 CID,
#要嵌入内联图片,在邮件视图中使用 $message 变量上的embed 方法即可
#Laravel 在所有邮件视图中注入 $message 变量并使其自动有效
<body>
    Here is an image:

    <img src="{{ $message->embed($pathToFile) }}">
</body>

#嵌入原生数据附件
<body>
    Here is an image from raw data:

    <img src="{{ $message->embedData($data, $name) }}">
</body>

生成 Markdown 邮件类 — Laravel 5.4+

// --markdown=emails.orders.shipped 对应视图自动生成
php artisan make:mail OrderShipped --markdown=emails.orders.shipped

配置可邮寄类的 build 方法时,使用 markdown 方法取代 view 方法。markdown 方法接收 Markdown 模板的名称和一个可选的在模板中生效的数组数据:

@component('mail::message')
# Order Shipped

Your order has been shipped!

@component('mail::button', ['url' => $url])
View Order
@endcomponent

Thanks,<br>
{{ config('app.name') }}
@endcomponent

发送邮件
事件