イントロダクション
Laravelは人気の高いSwiftMailerライブラリーのクリーンでシンプルなAPIを提供しています。SMTP、Mailgun、Mandrill、SparkPost、Amazon
SES、PHPのmail
機能、sendmail
ドライバーを提供しており、選択したローカルやクラウドベースのサービスを使い、素早くメール送信が開始できるようにしています。
ドライバの動作要件
MailgunとMandrillなどAPIベースドライバはシンプルでSMTPサーバーよりも高速です。APIドライバは全てGuzzle
HTTPライブラリーをアプリケーションにインストールする必要があります。以下の行をcomposer.json
ファイルに追加し、Guzzle
5をプロジェクトに追加してください。
"guzzlehttp/guzzle": "~5.3|~6.0"
Mailgunドライバ
Mailgunドライバを使用する場合、最初にGuzzleをインストールしてください。それからconfig/mail.php
設定ファイル中のdriver
オプションをmailgun
に設定してください。次にconfig/services.php
設定ファイルが以下のオプションを含んでいるか確認してください。
'mailgun' => [
'domain' => 'your-mailgun-domain',
'secret' => 'your-mailgun-key',
],
Mandrillドライバ
Mandrillドライバを使用するには、最初にGuzzleをインストールし、次にconfig/mail.php
設定ファイル中のdriver
オプションをmandrill
に設定してください。それからconfig/services.php
設定ファイルに以下のオプションが含まれているか確認してください。
'mandrill' => [
'secret' => 'your-mandrill-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
セクションに以下の行を追加し、このライブラリーをインストールします。
"aws/aws-sdk-php": "~3.0"
次にconfig/mail.php
設定ファイルのdriver
オプションをses
に設定します。それからconfig/services
設定ファイルが以下の内容になっているか確認してください。
'ses' => [
'key' => 'your-ses-key',
'secret' => 'your-ses-secret',
'region' => 'ses-region', // e.g. us-east-1
],
メール送信
Laravelではメールのメッセージをビューとして保存します。たとえばメールを系統立てて利用するためにresources/views
ディレクトリにemails
ディレクトリを作成することができます。
メッセージを送るにはMail
ファサードのsend
メソッドを使います。send
メソッドは3つの引数を取ります。第1引数はメールの内容を含んでいるビューの名前です。第2引数はビューに渡すデータの配列です。第3引数はメッセージインスタンスを受け取る「クロージャ」のコールバックで、受信者や主題、もしくは他のメールの項目をカスタマイズできます。
<?php
namespace App\Http\Controllers;
use Mail;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* ユーザーにメールでリマインダーを送信
*
* @param Request $request
* @param int $id
* @return Response
*/
public function sendEmailReminder(Request $request, $id)
{
$user = User::findOrFail($id);
Mail::send('emails.reminder', ['user' => $user], function ($m) use ($user) {
$m->from('hello@app.com', 'Your Application');
$m->to($user->email, $user->name)->subject('Your Reminder!');
});
}
}
上の例ではuser
キーを含んだ配列を渡していますので、以下のPHPコードにより、メールの中にユーザ名を挿入することができます。
<?php echo $user->name; ?>
注目:
$message
変数はいつもメールのビューに渡され、添付のインライン埋め込みが行えます。そのためビュー本体にmessage
変数を渡す必要はありません。
メッセージの組み立て
前述の通り、send
メソッドの第3引数は「クロージャ」で、メールの様々なオプションを指定できます。このクロージャを使用しCCやBCCなどメッセージの他の属性を指定することもできます。
Mail::send('emails.welcome', $data, function ($message) {
$message->from('us@example.com', 'Laravel');
$message->to('foo@example.com')->cc('bar@example.com');
});
$message
メッセージビルダで使用できるメソッドの一覧です。
$message->from($address, $name = null);
$message->sender($address, $name = null);
$message->to($address, $name = null);
$message->cc($address, $name = null);
$message->bcc($address, $name = null);
$message->replyTo($address, $name = null);
$message->subject($subject);
$message->priority($level);
$message->attach($pathToFile, array $options = []);
// $data文字列をそのまま付属ファイルへ
$message->attachData($data, $name, array $options = []);
// 裏で動作するSwiftMailerメッセージインスタンスの取得
$message->getSwiftMessage();
注目:
Mail::send
クロージャに渡されるメッセージインスタンスは、SwiftMailerメッセージクラスを拡張していますので、メールメッセージを構築するためにこのクラスのメソッドを呼び出すことができます。
平文のメール
デフォルトでsend
メッソッドに指定するビューはHTMLで構成されているでしょう。しかしsend
メソッドの第1引数として配列を指定すると、HTMLビューに加えて平文テキストビューを指定できます。
Mail::send(['html.view', 'text.view'], $data, $callback);
もしくは平文テキストメールだけを送る必要があるなら、配列でtext
キーを指定することもできます。
Mail::send(['text' => 'view'], $data, $callback);
ロウ(raw)文字列
文字列を直接そのままメールしたい場合は、raw
メソッドを使ってください。
Mail::raw('Text to e-mail', function ($message) {
//
});
添付
メールに添付する場合は、クロージャに渡される$message
オブジェクトのattach
メソッドを使用します。attach
メソッドでは最初の引数としてファイルの完全パスを指定します。
Mail::send('emails.welcome', $data, function ($message) {
//
$message->attach($pathToFile);
});
ファイルをメッセージ添付する場合、attach
メソッドの第2引数として配列を渡し、表示名やMIMEタイプを指定することもできます。
$message->attach($pathToFile, ['as' => $display, 'mime' => $mime]);
attachData
メソッドははロウ文字列のバイトを添付するために使用します。たとえば、PDFをメモリ上で生成し、ディスクに書き出さすに添付したい場合に利用できます。
$message->attachData($pdf, 'invoice.pdf');
$message->attachData($pdf, 'invoice.pdf', ['mime' => $mime]);
インライン添付
メールのビューに画像を埋め込む
メールに画像をインラインで埋め込むことは典型的な厄介事です。しかしLaravelは画像をメールに付け、最適なCIDを得る便利な方法を提供しています。インラインイメージを埋め込むには、メールビューの中で$message
変数のembed
メソッドを使ってください。Laravelは全メールビューで自動的に$message
変数を使用できるようにしていることを思い出してください。
<body>
ここに画像:
<img src="<?php echo $message->embed($pathToFile); ?>">
</body>
メールのビューにロウ(raw)データーを埋め込む
メールメッセージへ埋め込む生データ文字列を既に用意してある場合は、$message
のembedData
メソッドを使ってください。
<body>
ここにロウデータからの画像:
<img src="<?php echo $message->embedData($data, $name); ?>">
</body>
キュー使用メール
メールメッセージのキューイング
メール送信はアプリケーションのレスポンスをとても遅くしてしまうため、多くの開発者はメールメッセージをバックグラウンドでキュー送信するようにしています。Laravelでは組み込みの共通キューAPIを使用することで、簡単に取り扱えるようになっています。メールメッセージをキューに投入するには、Mail
ファサードのqueue
メソッドを使用するだけです。
Mail::queue('emails.welcome', $data, function ($message) {
//
});
このメソッドはバックグラウンドでメールを送信するため、自動的にジョブをキューに投入する面倒を見ます。もちろんこの機能を使用する前にキューの設定を行う必要があります。
遅延メッセージキュー
キューに投入したメールメッセージを送らせて配信したい場合はlater
メソッドを使用してください。メソッドの最初の引数として、メッセージ送信を遅らせたい秒数を指定するだけです。
Mail::later(5, 'emails.welcome', $data, function ($message) {
//
});
特定のキューに投入
メッセージを投入するキューを指定したい場合、queueOn
かlaterOn
メソッドを使用します。
Mail::queueOn('queue-name', 'emails.welcome', $data, function ($message) {
//
});
Mail::laterOn('queue-name', 5, 'emails.welcome', $data, function ($message) {
//
});
メールとローカル開発
メールを送信するアプリケーションを開発している間は、実際のメールアドレスにメールを送信したくはありません。Laravelはメールメッセージを実際に送信することを「無効」にする、様々な方法を用意しています。
Logドライバ
一つの解決方法は、ローカルでの開発期間中にlog
メールドライバを使用することです。このドライバは確認できるように全メールメッセージをログに書き込みます。環境ごとのアプリケーションの設定についての情報は、設定のドキュメントで確認してください。
全メールの送信先指定
Laravelが提供するもう一つの解決策は、フレームワークが送信する全メールの共通受け取り先を設定する方法です。この方法を使うと送信メッセージに指定した実際のアドレスの代わりに、アプリケーションが送る全メールを特定のアドレスに送信します。この方法を使用する場合、config/mail.php
設定ファイルでto
オプションを指定します。
'to' => [
'address' => 'dev@domain.com',
'name' => 'Dev Example'
],
Mailtrap
最後の方法はMailtrapのようなサービスを使い、smtp
ドライバで本当のメールクライアントにより内容を確認できる「ダミー」のメールボックスへメールメッセージを送る方法です。このアプローチの利点は最終的なメールをMailtrapのメッセージビュアーで実際に確認できることです。
イベント
Laravelはメールメッセージを送信する直前に、イベントを発行します。このイベントは、メールが送られる場合に発行されますが、キューイングされる場合には発行されないことに留意してください。EventServiceProvider
へ、イベントリスナーを登録します。
/**
* アプリケーションへマッピングするイベントリスナー
*
* @var array
*/
protected $listen = [
'Illuminate\Mail\Events\MessageSending' => [
'App\Listeners\LogSentMessage',
],
];