Laravel 5.3 メール

イントロダクション

Laravelは人気の高いSwiftMailerライブラリーのクリーンでシンプルなAPIを提供しています。SMTP、Mailgun、SparkPost、Amazon SES、PHPのmail機能、sendmailドライバーを提供しており、選択したローカルやクラウドベースのサービスを使い、素早くメール送信が開始できるようにしています。

ドライバの動作要件

MailgunとSparkPostなどAPIベースドライバはシンプルでSMTPサーバーよりも高速です。可能であれば、こうしたドライバを使用しましょう。APIドライバはすべて、Guzzle HTTPライブラリを必要としますので、Composerパッケージマネージャでインストールしてください。

composer require guzzlehttp/guzzle

Mailgunドライバ

Mailgunドライバを使用する場合、最初にGuzzleをインストールしてください。それからconfig/mail.php設定ファイル中のdriverオプションをmailgunに設定してください。次にconfig/services.php設定ファイルが以下のオプションを含んでいるか確認してください。

'mailgun' => [
    'domain' => 'your-mailgun-domain',
    'secret' => 'your-mailgun-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セクションに以下の行を追加し、composer updateコマンドを実行します。

"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',  // e.g. us-east-1
],

Mailable概論

Laravelではアプリケーションが送信する、各種メールタイプを"mailable"クラスとして表します。これらのクラスは、app/Mailディレクトリに保存します。アプリケーションにこのディレクトリが存在していなくても、心配ありません。make:mailコマンドを使用して、最初にmailableクラスを生成する時に、作成されます。

php artisan make:mail OrderShipped

Mailableプログラミング

全mailableクラスの設定は、buildメソッド中で行います。このメソッド中でメールのプレゼンテーションとデリバリーを設定する、fromsubjectviewattachなど様々なメソッドを呼び出します。

Senderの設定

fromメソッドの使用

最初に、メールの送信者の設定を見てみましょう。言い換えれば、"from"により、メールを送信する人を指定します。送信者の設定には2つの方法があります。最初にmailableクラスのbuildメソッドの中で、fromメソッドを使う方法です。

/**
 * メッセージの生成
 *
 * @return $this
 */
public function build()
{
    return $this->from('example@example.com')
                ->view('emails.orders.shipped');
}

グローバルfromアドレスの使用

もし、アプリケーションで同じ"from"アドレスを全メールで使用するのであれば、生成する全mailableクラスでfromメソッドを呼び出すのは面倒です。代わりに、グローバルな"from"アドレスをconfig/mail.php設定ファイルで指定しましょう。このアドレスは、mailableクラスの中で、"from"アドレスが指定されなかった場合に使用されます。

'from' => ['address' => 'example@example.com', 'name' => 'App Name'],

ビューの設定

mailableクラスのbuildメソッドの中で、メールの中身をレンダーする時に使用するテンプレートをviewメソッドにより指定できます。各メールでは内容をレンダーするのにBlade テンプレートを通常使用しますので、メールのHTMLを構築する時にBladeテンプレートエンジンのパワーと利便性をフルに利用できます。

/**
 * メッセージの生成
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped');
}

Tip!! メール用テンプレートをすべて設置する、resources/views/emailsディレクトリを作成することができます。しかし、resources/viewsディレクトリの中であれば、好きな場所へ自由に設置できます。

平文テキストメール

平文テキスト版のメールを定義したいときは、textメソッドを使います。viewメソッドと同様に、textメソッドは、メールの内容をレンダーするために使用する、テンプレート名を引数に取ります。メッセージのHTML版と平文テキスト版の両方を定義することも可能です。

/**
 * メッセージの生成
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->text('emails.orders.shipped_plain');
}

ビューデータ

publicプロパティ使用

通常、メールのHTMLをレンダーする時には、ビューへ使用するデータを渡します。ビューでデータを使用できるようにするには、2つの方法があります。まず、mailableクラスで定義したpublicプロパティは、ビューで自動的に利用できます。そのため、たとえばmailableクラスのコンストラクタへデータを渡し、そのデータをクラス上のプロパティとして定義できます。

<?php

namespace App\Mail;

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

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * 注文インスタンス
     *
     * @var Order
     */
    public $order;

    /**
     * 新しいメッセージインスタンスの生成
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped');
    }
}

データをpublicプロパティにセットしたら、自動的にビューで使用できるようになり、Bladeテンプレート中で、他のデータと同様にアクセスできます。

<div>
    Price: {{ $order->price }}
</div>

withメソッド使用

メールのデータフォーマットをテンプレートへ渡す前にカスタマイズしたい場合は、withメソッドを使いデータをビューへ渡すことができます。通常、この場合もデータをmailableクラスのコンストラクタで渡すことになるでしょう。しかし、自動的にテンプレートで使用可能にならないように、protectedprivateプロパティへデータをセットしてください。それから、テンプレートで使用したいデータの配列を引数として、withメソッドを呼び出してください。

<?php

namespace App\Mail;

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

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * 注文インスタンス
     *
     * @var Order
     */
    protected $order;

    /**
     * 新しいメッセージインスタンスの生成
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->with([
                        'orderName' => $this->order->name,
                        'orderPrice' => $this->order->price,
                    ]);
    }
}

withメソッドへ渡したデータは、ビューで自動的に使用可能になり、Bladeテンプレートの他のデータと同様にアクセスできます。

<div>
    Price: {{ $orderPrice }}
</div>

添付

メールへ添付するには、attachメソッドをmailableクラスのbuildメソッド中で呼び出します。attachメソッドは最初の引数に、ファイルのフルパスを取ります。

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attach('/path/to/file');
    }

ファイルをメッセージ添付する場合、attachメソッドの第2引数として配列を渡し、表示名やMIMEタイプを指定することもできます。

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attach('/path/to/file', [
                        'as' => 'name.pdf',
                        'mime' => 'application/pdf',
                    ]);
    }

Rawデータ添付

attachDataメソッドは添付内容のバイト文字列をそのまま添付する場合に使用します。たとえば、メモリ中でPDFを生成し、それをディスクに書き出さずに、メールへ添付したい場合にこのメソッドを使用できます。attachDataメソッドはrawデータバイトを最初の引数に取り、ファイル名を第2引数に、オプションの配列を第3引数に取ります。

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attachData($this->pdf, 'name.pdf', [
                        'mime' => 'application/pdf',
                    ]);
    }

インライン添付

インライン画像をメールに埋め込むのは、通常手間がかかります。しかし、Laravelは画像をメールに付け、最適なCIDを得る便利な方法を提供しています。インラインイメージを埋め込むには、メールビューの中で$message変数のembedメソッドを使ってください。Laravelでは全メールテンプレートで、$message変数が使用できるようになっていますので、この変数を渡すことについては心配する必要はありません。

<body>
    ここに画像:

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

添付Rawデータの埋め込み

メールテンプレートへ埋め込むrawデータ文字列を既に用意してある場合は、$message変数のembedDataメソッドを使ってください。

<body>
    ここにrawデータからの画像:

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

メール送信

メッセージを送信するには、Mailファサードtoメソッドを使います。toメソッドはメールアドレス、ユーザインスタンス、もしくはユーザのコレクションを引数に取ります。一つのオブジェクト、もしくはオブジェクトのコレクションを渡すと、メーラは自動的にそれらのemailnameプロパティを使用します。そのため、オブジェクトで、その属性を確実に使用可能にしてください。送信先を指定し終えたら、mailableクラスのインスタンスをsendメソッドへ渡してください。

<?php

namespace App\Http\Controllers;

use App\Order;
use App\Mail\OrderShipped;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Http\Controllers\Controller;

class OrderController extends Controller
{
    /**
     * 注文の配送
     *
     * @param  Request  $request
     * @param  int  $orderId
     * @return Response
     */
    public function ship(Request $request, $orderId)
    {
        $order = Order::findOrFail($orderId);

        // 配送処理…

        Mail::to($request->user())->send(new OrderShipped($order));
    }
}

もちろん、メール送信時に"to"で受取人を指定するだけに限りません。"to"、"cc"、"bcc"による受取人をすべて一つのメソッドチェーンで呼び出せます。

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->send(new OrderShipped($order));

キュー使用メール

メールメッセージのキューイング

メールメッセージを送ることにより、アプリケーションのレスポンス時間が極端に長くなり得るため、多くの開発者はメールメッセージをバックグランドで送信するためにキューイングすることを選びます。Laravelの統一されたキューAPIを使うことで、簡単に実現できます。メールメッセージをキューへ送るには、Mailファサードへ、受取人の指定の後に、queueメソッドを使います。

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue(new OrderShipped($order));

このメソッドはバックグラウンドでメールを送信するため、自動的にジョブをキューに投入する面倒を見ます。もちろん、この機能を使用する前にキューの設定を行う必要があります。

遅延メッセージキュー

メッセージを投入するキューを指定したい場合、laterOnメソッドを使用します。最初の引数に、laterメソッドは、メッセージを送信する時間を示すDateTimeインスタンスを受け取ります。

$when = Carbon\Carbon::now()->addMinutes(10);

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->later($when, new OrderShipped($order));

特定のキューに投入

make:mailコマンドにより生成されたmailableクラスにはすべて、Illuminate\Bus\Queueableトレイトが使用されています。接続とキュー名を指定する、onQueueonConnectionメソッドをすべてのmailableクラスインスタンスで呼び出せます。

$message = (new OrderShipped($order))
                ->onConnection('sqs')
                ->onQueue('emails');

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue($message);

デフォルトとしてキュー投入

いつもMailableクラスをキューへ投入したければ、クラスへShouldQueue契約を実装してください。それで、メール送信時にsendメソッドを呼びだせば、そのMailableクラスは契約が実装されていますので、いつもキューイングされます。

use Illuminate\Contracts\Queue\ShouldQueue;

class OrderShipped extends Mailable implements ShouldQueue
{
    //
}

メールとローカル開発

メールを送信するアプリケーションを開発している間は、実際のメールアドレスにメールを送信したくはありません。Laravelはメールメッセージを実際に送信することをローカルでの開発期間の間、「無効」にする様々な方法を用意しています。

Logドライバ

メールを送信する代わりに、logメールドライバで、すべてのメールメッセージを確認のためにログファイルへ書き込こめます。アプリケーションの設定に関する詳細は、設定のドキュメントを確認してください。

全メールの送信先指定

Laravelが提供するもう一つの解決策は、フレームワークが送信する全メールの共通受け取り先を設定する方法です。この方法を使うと送信メッセージに指定した実際のアドレスの代わりに、アプリケーションが送る全メールを特定のアドレスに送信します。この方法を使用する場合、config/mail.php設定ファイルでtoオプションを指定します。

'to' => [
    'address' => 'example@example.com',
    'name' => 'Example'
],

Mailtrap

最後の方法はMailtrapのようなサービスを使い、smtpドライバで本当のメールクライアントにより内容を確認できる「ダミー」のメールボックスへメールメッセージを送る方法です。このアプローチの利点は最終的なメールをMailtrapのメッセージビュアーで実際に確認できることです。

イベント

Laravelはメールメッセージを送信する直前に、イベントを発行します。メールが実際に送信される場合に、このイベントを発行しますが、キューイングする場合には発行されないことに留意してください。EventServiceProviderへ、イベントリスナーを登録します。

/**
 * アプリケーションへマッピングするイベントリスナー
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Mail\Events\MessageSending' => [
        'App\Listeners\LogSentMessage',
    ],
];

ドキュメント章別ページ

開発環境
ビューとテンプレート
Artisanコンソール
公式パッケージ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

バージョン

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる