Laravel 5.7 以队列方法发送邮件(三种场景)
laravel 5.7 自带了Email verification 的功能,使得整个邮件注册激活过程更加简单。注册用户时发送激活邮件、重新发送邮件、密码重置邮件,这些功能几乎都是 Out of box的。但默认都是同步发送,太慢了,所以改为队列异步发送!当然,前提是你已经开启了redis队列并且已经理解了5.7的这些邮件发送处理流程。
1. 注册时发送邮件
- 创建发送注册邮件的job
php artisan make:job SendRegisterUserEmail
-
job类的代码如下:
class SendRegisterUserEmail implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $user; /** * Create a new job instance. * * @param $user */ public function __construct($user) { $this->user = $user; } /** * Execute the job. * * @return void */ public function handle() { event(new Registered($this->user)); } }
- 新增
\App\Http\Controllers\Auth\RegisterController::register
来覆盖\Illuminate\Foundation\Auth\RegistersUsers::register
,因为发送邮件是在这个方法中进行的。代码如下:/** * Handle a registration request for the application. * * @param Request $request * * @return \Illuminate\Http\Response */ public function register(Request $request) { $this->validator($request->all())->validate(); $user = $this->create($request->all()); //队列job发送邮件 dispatch(new SendRegisterUserEmail($user)); $this->guard()->login($user); return $this->registered($request, $user)?: redirect($this->redirectPath()); }
2. 重新发送邮件
- 在
app/Http/Controllers/Auth/VerificationController.php
中新增resend
方法,来复写trait VerifiesEmails
中 的方法,从而队列异步发送邮件。代码如下:/** * Resend the email verification notification. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function resend(Request $request) { if ($request->user()->hasVerifiedEmail()) { return redirect($this->redirectPath()); } //队列job发送邮件 dispatch(new SendRegisterUserEmail($request->user())); return back()->with('resent', true); }
3. 重置密码邮件
- php artisan make:job SendResetPasswordEmail
-
修改
SendResetPasswordEmail
中的代码,如下:class SendResetPasswordEmail implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $user; protected $token; /** * Create a new job instance. * * @param User $user * @param $token */ public function __construct(User $user, $token) { $this->user = $user; $this->token = $token; } /** * Execute the job. * * @return void */ public function handle() { $this->user->notify(new ResetPassword($this->token)); } }
- 修改
\App\Models\User::sendPasswordResetNotification
这个方法,代码如下:/** * Send the password reset notification. * * @param string $token * * @return void */ public function sendPasswordResetNotification($token) { dispatch(new SendResetPasswordEmail($this, $token)); }
4.注意:开启Redis队列发送邮件,一定要注意代码缓存问题。详见《一次对 horizon 是否缓存的误判,导致怀疑 Redis 有 BUG,最终自己解决的经历》
All Done!
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
推荐文章: