5.3より新しくなったLaravelのメール機能についてのまとめです。

確認したバージョン

  • PHP 7.0.x
  • Laravel 5.4

Laravelのメール機能は5.3から新しくなっています。

Laravel Mail

Laravel > Mail
http://laravel.com/docs/5.4/mail

Laravelのメール機能をざっくり説明すると次のように役割を分担しています。

  • Bladeテンプレートに本文を書く
  • Mailableクラスで件名や本文を指定する
  • Mailクラスで送信処理を行う

また、Laravel内部ではSwiftMailerを利用しています。
https://github.com/swiftmailer/swiftmailer

ドライバ

メール送信サービスのMailgun、AWSAmazon SESに対応しています。
もちろんsmtpも利用できますよ。

実装してみる

Mailableクラスの追加

In Laravel, each type of email sent by your application is represented as a “mailable” class.

Laravelではメールの種類/内容をMailableと呼称するクラスに定義します。

artisan(アルチザン)コマンドからクラスを生成します。

1$ php artisan make:mail Greet

コマンド実行後、App\Mail\Mail.phpが生成されます。
生成直後のクラスです。

 1<?php
 2
 3namespace App\Mail;
 4
 5use Illuminate\Bus\Queueable;
 6use Illuminate\Mail\Mailable;
 7use Illuminate\Queue\SerializesModels;
 8use Illuminate\Contracts\Queue\ShouldQueue;
 9
10class Greet extends Mailable
11{
12    use Queueable, SerializesModels;
13
14    /**
15     * Create a new message instance.
16     *
17     * @return void
18     */
19    public function __construct()
20    {
21        //
22    }
23
24    /**
25     * Build the message.
26     *
27     * @return $this
28     */
29    public function build()
30    {
31        return $this->view('view.name');
32    }
33}
34

viewでBladeテンプレートを指定します。
テンプレートについては後述します。

Mailableの編集

build()でメール本文や件名の指定を行います。

Mailableはコンストラクタを経由して各種データを受け取るのがお作法のようです。
実装例を示します。

 1class OrderShipped extends Mailable
 2{
 3    use Queueable, SerializesModels;
 4
 5    protected $options;
 6    protected $content;
 7    protected $attach;
 8
 9    public function __construct($options, $content, $attach)
10    {
11        $this->options = $options;
12        $this->content = $content;
13        $this->attach  = $attach;
14    }
15    public function build()
16    {
17        return $this
18            ->from($options['from'], $options['from_name'])
19            ->subject($options['subject'])
20            ->attachData($this->attach['binary'], $this->attach['file_name']);
21            ->view('emails.greet')
22            ->with([
23                'content' => $content,
24            ]);
25    }
26}
27

添付ファイルが複数の場合など、次のように書くこともできます。
メソッドチェーンではなくてもOK。

1public function build()
2{
3    foreach ($this->attaches as $attach) {
4        $this->attachData($attach['binary'], $attach['file_name']);      
5    }
6    :
7

先のLaravel5.4ドキュメントにはあまりオプションが見受けられませんが、5.1ではオプションの一覧が掲載されていました。
https://laravel.com/docs/5.1/mail#sending-mail

上記より引用します。
これだけあれば事足りるでしょう。

 1$message->from($address, $name = null);
 2$message->sender($address, $name = null);
 3$message->to($address, $name = null);
 4$message->cc($address, $name = null);
 5$message->bcc($address, $name = null);
 6$message->replyTo($address, $name = null);
 7$message->subject($subject);
 8$message->priority($level);
 9$message->attach($pathToFile, array $options = []);
10
11// Attach a file from a raw $data string...
12$message->attachData($data, $name, array $options = []);
13
14// Get the underlying SwiftMailer message instance...
15$message->getSwiftMessage();
16

なお、Laravelのバージョンは変わっても、この辺りはSwiftMailerなので、同様に利用できるようですね。

テンプレート

テンプレートは単なるLaravelのBladeテンプレートファイルです。
変数の私方が異なるくらいで、コントローラーからviewを呼び出す場合とほとんど同じ感覚で使うことができます。

1Atuwebからのご挨拶です。
2
3{{ $content['hoge'] }}
4{{ $content['fuga'] }}

@if@foreachも利用できます。


ファイル格納場所はresources/views以下です。
Laravelのドキュメントにならって[resources/views/emails]にまとめておくと良さそうです。

テンプレートの生成

5.4より、artisanコマンド実行時にテンプレートを生成できるようになりました。

次のいずれかのようにコマンドを実行します。

1$ php artisan make:mail Greet -m emails.greet
2$ php artisan make:mail Greet --markdown=emails.greet

--markdownの示す通り、5.4からはHTMLメールのテンプレートにmarkdownが書けるようになっています。

上記オプション付加した場合、Mailable.build()にmarkdown()がセットされています。

1public function build()
2{
3    return $this->markdown('emails.greet');
4}
5

私は、テンプレートを別途用意するのが面倒なため、サクッとコマンドで用意して上記を書き換えています。

プレーンテキスト/HTMLメール/マークダウン

Mailableクラスで指定したBladeテンプレートをどう処理するかは、呼び出すメソッドで指定します。

プレーンテキスト

プレーンテキストのメールとする場合、text()を呼び出します。
これが、意外とわかりませんでした。

1public function build()
2{
3    return $this->text('emails.greet');
4}
5

テンプレートの開業がそのままメール本文に反映されます。

HTMLメール

view()はテンプレートをHTMLメールとして扱います。

1public function build()
2{
3    return $this->view('emails.greet');
4}
5

Markdown

markdown()は、テンプレート中のmarkdownを解釈してくれるHTMLメールを生成します。

1public function build()
2{
3    return $this->markdown('emails.greet');
4}
5

メール送信

1\Mail::to($addresses)
2    ->send(new \App\Mail\Greet($options, $content, $attach));
3

メールはキューに入れたり遅延させることもできますね。

キューに入れるにはsend()のかわりにqueue()を呼び出します。

1\Mail::to($addresses)
2    ->queue(new \App\Mail\Greet($options, $content, $attach));
3

遅延送信を行う場合はlater()にCarbonオブジェクトとMailableオブジェクトを与えます。

1$when = \Carbon\Carbon::now()->addMinutes(10);
2
3\Mail::to($addresses)
4    ->later($when, new \App\Mail\Greet($options, $content, $attach));
5

わかりやすいですね。

おわりに

かつてはメールヘッダを手動で書くなど、細々と面倒だったメール送信も非常に簡単に処理できますね。 便利です。

楽しい開発ライフをお過ごしください。


PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応

竹澤 有貴,栗生 和明,新原 雅司,大村 創太郎
出版社:ソシム  発売日:2018-09-26

Amazonで詳細を見る

PHPフレームワーク Laravel入門

掌田津耶乃
出版社:秀和システム  発売日:2017-09-16

Amazonで詳細を見る

初めてのPHP

David Sklar
出版社:オライリージャパン  発売日:2017-03-18

Amazonで詳細を見る