「サンクスメールを送信するとかの処理は即時じゃなくてもいいから、サイトのレスポンスはとにかく速く」という雰囲気になった時はLaravel/Lumenのキューを使う機会が来たということじゃないでしょうか。
というわけで、ちょっとやってみました。
前提
- サンプルコードはLumen5.1です(Laravel5.1~5.3でも確認済です)
- キュードライバは、データベースドライバを使います。
- 設定はこの記事の下の方にある「補足」の通りです。
Laravel/Lumenのキューに対する自分の中の理解
ジョブクラスのインスタンスをjobsテーブルに登録すると、Laravel/Lumenがジョブをキューとして実行していってくれる。
やる事
- jobsテーブルを作成する
- ジョブクラスを作成する
- キューリスナーを実行する
1.jobsテーブルを作成する
これはドキュメントにある通り、マイグレーションファイルを生成して、マイグレーションを実行します。
php artisan queue:table
php artisan migrate
2.ジョブクラスを作成する
これもドキュメントにある通りですが、以下のようにプロパティを使う場合は必ず指定しとかないと、キューの実行時に例外を投げよります。
<?php
namespace App\Jobs;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendEmail extends Job implements SelfHandling, ShouldQueue {
/** @var string view name */
protected $view;
/** @var array ビューに割り当てるデータ */
protected $data;
/** @var array メールの送信先等の属性 */
protected $mail;
public function __construct($view, $data, $mail)
{
$this->view = $view;
$this->data = $data;
$this->mail = $mail;
}
/**
* @param Mailer $mailer
*/
public function handle(Mailer $mailer)
{
$mail = $this->mail;
$mailer->send($this->view, $this->data, function ($message) use ($mail)
{
$message->subject($mail['subject'])
->from($mail['from'], $mail['f_name'])
->to($mail['to'], $mail['to_name']);
});
}
}
Laravel5.3ではクラスの継承などが以下のように変更されています。
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendEmail implements ShouldQueue {
use InteractsWithQueue, Queueable, SerializesModels;
/** @var string view name */
protected $view;
/** @var array ビューに割り当てるデータ */
protected $data;
/** @var array メールの送信先等の属性 */
protected $mail;
public function __construct($view, $data, $mail)
{
$this->view = $view;
$this->data = $data;
$this->mail = $mail;
}
/**
* @param Mailer $mailer
*/
public function handle(Mailer $mailer)
{
$mail = $this->mail;
$mailer->send($this->view, $this->data, function ($message) use ($mail)
{
$message->subject($mail['subject'])
->from($mail['from'], $mail['f_name'])
->to($mail['to'], $mail['to_name']);
});
}
}
3.キューリスナーを実行する
これもまたドキュメントにある通りです。
php artisan queue:listen
ジョブのインスタンスをjobsテーブルに登録する
今回は、ブラウザ経由でジョブを登録するので、ラウティングとコントローラーを作成します。
メールのテンプレートにビューファイルを使用するのでついでに作成します。
(laravel5.3ではラウティングファイルにroutes/web.php
を使います)
<?php
// for Lumen 5.1
$app->get('reserve', 'ReserveController@store');
// for Laravel 5.1(LTS) ~ 5.3
Route::get('reserve', 'ReserveController@store');
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Jobs\SendEmail;
class ReserveController extends Controller {
public function store()
{
$mail = [
'from' => 'nielsen@test.com',
'f_name' => 'Nelsen',
'to' => 'poulsen@test.com',
'to_name' => 'Poulsen',
'subject' => 'Thanks for your reservation.'
];
// ジョブのインスタンスを生成
$job = new SendEmail(
'emails.reservation',
['name' => ucfirst('niikunihiro')],
$mail
);
// jobs テーブルに登録
$this->dispatch($job);
echo 'finished!';
}
}
Hi! {{$name}}.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab dolor eius eos hic magnam minus, nihil odio omnis quae quas velit, veritatis. Assumenda earum porro, quisquam repellendus sed tempora voluptatibus.
ブラウザで確認するので、ビルトインサーバを立ち上げます。
php artisan serve
「http://localhost:8000/reserve」にアクセスすると、ログファイルにメールの内容が書込まれているので確認して終わりです。
[2015-07-11 07:14:46] lumen.DEBUG: Message-ID: <84c77b0b510235de0e6a54621294c3ef@swift.generated>
Date: Sat, 11 Jul 2015 07:14:46 +0000
Subject: Thanks for your reservation.
From: Nelsen <nielsen@test.com>
To: Poulsen <poulsen@test.com>
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
Hi! Niikunihiro.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab dolor eius eos hic magnam minus, nihil odio omnis quae quas velit, veritatis. Assumenda earum porro, quisquam repellendus sed tempora voluptatibus.
補足
設定ファイル
# APP_KEY に 32 文字の乱数(じゃなくてもいいけど)を設定する
# APP_KEY が正しく設定されてないとエラーになります
APP_KEY=Dwwf1OGD9vriSvpWIZhDubkPKWdnNgSi
# データベースドライバを使用
QUEUE_DRIVER=database
# 送信内容をログで見たいので
MAIL_DRIVER=log
Lumenの場合は、illuminate/mail
パッケージを追加する
{
"require": {
"laravel/lumen-framework": "5.1.*",
"vlucas/phpdotenv": "~1.0",
"illuminate/mail": "5.1.*"
},
}
composer update illuminate/mail