個人的な学習でLaravelのMailable
クラスを使用してMail送信機能についてまとめてみました。
MailableクラスはLaravel 5.3から使用することができます。
僕自身が書いたコードはこちら
環境
今回は Laravel5.6.x、PHPは7.2.xを使用しています。
ドライバ
Laravelでは、APIベースのドライバであるMailgun、SparkPost、Amazon SESを使用することができ、かつSMTPよりも高速に動作します。今回はAmazon SESを使用していきます。
まずはこれらのAPIドライバを使用するために、ComposerよりGuzzle HTTPライブラリをインストールしていきます。
$ composer require guzzlehttp/guzzle
さらにAmazon SESドライバを使用する場合は、Amazon AWS SDK for PHPのインストールが必要となります。
comporser.json
のrequire
セクションを以下のように編集。
"require": { "php": "^7.1.3", "fideloper/proxy": "^4.0", "guzzlehttp/guzzle": "^6.3", "laravel/framework": "5.6.*", "laravel/tinker": "^1.0", "aws/aws-sdk-php": "~3.0" // 追加 },
composer update
を実行します。
次にconfig/mail.php
のdriverオプションをsesに設定します。デフォルトでは以下のようになっていて、こちらに合わせて.env
を編集します。
'driver' => env('MAIL_DRIVER', 'smtp'),
config/services.php
も同じで、以下のようになってる箇所を.env
から指定していきます。
'ses' => [ 'key' => env('SES_KEY'), 'secret' => env('SES_SECRET'), 'region' => env('SES_REGION', 'us-east-1'), ],
.env
で最低限、以下の項目が指定されていれば実際に動かすことができました。
MAIL_DRIVER=ses SES_KEY= SES_SECRET= SES_REGION=
Amazon SESに関してはこちらを参考にさせて頂きました。
Mailableクラス
アプリケーションから送信されるMailの各種設定をMailable
クラスの方で行います。
make:mail
コマンドを使用し、Mailableクラスを生成していきます。
$ php artisan make:mail OrderShipped
生成されたクラスのbuild
メソッド内で各種設定を行います。
送信元の設定
from
メソッドを使用して送信元を設定します。
/** * Build the message. * * @return $this */ public function build() { return $this->from('example@example.com'); }
アプリケーションで同じ"from"アドレスを全メールで使用するのであれば、config/mail.php
でグローバルに指定することもできます。
'from' => [ 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), 'name' => env('MAIL_FROM_NAME', 'Example'), ],
こちらに合わせて、.env
を編集していきます。
また、Amazon SESを使用する場合、送信元の設定はAmazon SESで登録した送信メールアドレス(送信者認証を行ったメールアドレス)を登録しなければなりません。
ビューの設定
Mailable
クラスのbuild
メソッドの中で、view
メソッドを使用してviewを設定していきます。
メールの中身もBladeのテンプレートエンジンを使用したviewを使うことができます。
/** * Build the message. * * @return $this */ public function build() { return $this->view('emails.orders.shipped'); }
viewにデータを渡す
with
メソッドを使いviewにデータを渡すことができます。
<?php namespace App\Mail; use App\Order; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Queue\ShouldQueue; class OrderShipped extends Mailable { use Queueable, SerializesModels; /** * @var */ protected $order; // 新しいメッセージインスタンスの生成 /** * OrderShipped constructor. * * @param Order $order */ public function __construct(Order $order) { $this->order = $order; } /** * Build the message. * * @return $this */ public function build() { return $this->view('emails.orders.shipped') ->with([ // こちらでview側にデータを渡している 'orderName' => $this->order->name, 'orderPrice' => $this->order->price, ]); } }
今回は適当に以下のようなviewを作成してデータを受け取るようにしています。
resources/views/emails/orders.shipped.blade.php
<p>{{$orderName}}さん</p> <p>{{$orderPrice}}円のお支払いです。</p>
メールの送信
Mail
ファサードのto
メソッドを使い、宛先を指定することができます。
引数に直接メールアドレスを指定することも可能ですし、ユーザーインスタンス、もしくはユーザーのコレクションを指定することもできます。
Mailable
クラスのインスタンスをsend
メソッドへ渡すことで、メールを送信させることができます。
<?php namespace App\Http\Controllers; use App\Order; use App\Mail\OrderShipped; use Illuminate\Support\Facades\Mail; class OrderController extends Controller { public function ship($orderId) { $order = Order::findOrFail($orderId); Mail::to('hello@example.com')->send(new OrderShipped($order)); return redirect('/'); } }
routeも以下のように追加し、
<?php Route::get('/', function () { return view('welcome'); }); Route::get('order/{orderId}', 'OrderController@ship'); // 追加
適当にOrderインスタンスをtinkerなどから作成して、
/order/1
にアクセスすると
メールが送信されてることを確認できました!!
まとめ
Mailableクラスを使用することで、比較的簡単にMail送信機能を実装することができます。
Mail
ファサードのqueue
メソッドを使うことによってレスポンスの時間を待たず、バックグラウンドで処理(非同期)したりできるようなので、次回試してみます。