Laravelでメールを送信する処理を実装することになったのでMailableクラスを利用することにしました。
しかしMail::queue
メソッドで送信しようとしたときにエラーになってハマったのでメモ。
エラーについて
Mailableを継承したクラスは以下のように定義しました。
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Http\Request;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Eloquent\User;
class UserRegistered extends Mailable
{
use Queueable, SerializesModels;
public $request;
public $user;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(Request $request, User $user)
{
$this->request = $request;
$this->user = $user;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->view('emails.user_registered')
->to($this->request->input('email'), __('common.address_name', ['NAME' => $this->request->input('name')]))
->subject(\Config::get('mail.user_registered.subject_prefix').__('mail.mailsubject.user_registered'));
}
}
そして呼び元からはMail::queue
で送信。
\Mail::queue(new UserRegistered($request, $user));
送信できたかと思ったら以下のエラーになりました。
Serialization of 'Closure' is not allowed
/var/www/application/vendor/laravel/framework/src/Illuminate/Queue/Queue.php#128
しかし\Mail::queue
では送信できませんでしたが、\Mail::send
だと送信することができました。
なぜだろう?
環境
名前 | バージョン |
---|---|
PHP | 7.1.8 |
Laravel | 5.5.5 |
解決策
結論からいうと、
Serialization of 'Closure' is not allowed in Laravel 5.3 Email Queue
のリンクにあるとおり
You cannot serialize request. Only eloquent model can be serialized and unserialzed. See here: https://laravel.com/docs/5.2/queues#writing-job-classes
You should use$request->all()
instead of$request
. Since Request is treated as closure.
MailableオブジェクトにIlluminate\Http\Request
を渡していたからNGとのこと。
$request->all()
して配列を渡すように変更したところ\Mail::queue
でも送信することができるようになりました。
\Mail::queue(new UserRegistered($request, $user));
\Mail::queue(new UserRegistered($request->all(), $user));
当然Mailableオブジェクトの中身の処理も配列で渡ってくることを前提とした処理に変更しました。
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Eloquent\User;
class UserRegistered extends Mailable
{
use Queueable, SerializesModels;
public $inputs; // ★$request -> $inputsに変更しました
public $user;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(array $inputs, User $user)
{
$this->inputs = $inputs; // ★$request -> $inputsに変更しました
$this->user = $user;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
// ★$request -> $inputsに変更し配列から取得するようにしました
return $this->view('emails.user_registered')
->to($this->inputs['email'], __('common.address_name', ['NAME' => $this->inputs['name']]))
->subject(\Config::get('mail.user_registered.subject_prefix').__('mail.mailsubject.user_registered'));
}
}
これで無事queueでメールが送信されるようになりました!