如何排队 Laravel 5.7 "email verification" 邮件发送

How to queue Laravel 5.7 "email verification" email sending

Laravel 5.7 包含的 "email verification" 功能运行良好,但异步电子邮件发送(在用户注册或重新发送 link 页面期间)并不理想。

有没有什么方法可以通过队列发送电子邮件验证电子邮件,而无需在 Laravel 5.7 中重写整个电子邮件验证?

是的!这是可能的。为此,您必须重写 App\User 中的 sendEmailVerificationNotification。此方法由 Illuminate\Auth\MustVerfiyEmail 特性提供。方法 sendEmailVerificationNotification 通过发送 Illuminate\Auth\Notifications\VerifyEmail 通知 class 中定义的电子邮件通知创建的 user

// This is the code defined in the sendEmailVerificationNotification
public function sendEmailVerificationNotification()
{
    $this->notify(new Notifications\VerifyEmail);
}

您可以将此方法更改为不直接通知用户。您将必须定义一个 Job,您将在 sendEmailVerificationNotification 方法中分配它,而不是通知创建的用户。

Job class 中,您将创建一个 handle 方法,您可以在其中将电子邮件发送到 user,但您必须提供 $user 到作业,可以通过将其作为参数传递给 dispatch 方法来执行,如下所示:

public function sendEmailVerificationNotification()
{
    VerifyEmail::dispatch($this);
}

$this 表示创建的 userApp\Jobs\VerififyEmail 作业(您将创建的)将在其 [=30] 中接收传递给 dispatch 的所有参数=]

VerifyEmail 的代码如下所示:

namespace App\Jobs;

use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Auth\Notifications\VerifyEmail;

class VerifyEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        // Here the email verification will be sent to the user
        $this->user->notify(new VerifyEmail);
    }
}

没有内置方法,但您可以通过扩展和覆盖轻松实现。

首先,创建一个扩展内置通知的新通知,并实现 ShouldQueue 协定(以启用排队)。以下 class 假定您在 app/Notifications/VerifyEmailQueued.php 处创建通知:

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Notifications\VerifyEmail;

class VerifyEmailQueued extends VerifyEmail implements ShouldQueue
{
    use Queueable;

    // Nothing else needs to go here unless you want to customize
    // the notification in any way.
}

现在您需要告诉框架使用您的自定义通知而不是默认通知。您可以通过覆盖 User 模型上的 sendEmailVerificationNotification() 来做到这一点。这只是更改了发送的通知。

public function sendEmailVerificationNotification()
{
    $this->notify(new \App\Notifications\VerifyEmailQueued);
}

解决方法很简单:

Steps:

  1. 配置队列驱动程序

  2. 转到 --> Illuminate\Auth\Notifications\VerifyEmail

  3. 实现 'ShouldQueue' 接口并在上面提到的 class 上添加特征 'Queueable' 即 'VerifyEmail' 像这样:

class VerifyEmail 扩展通知实现 ShouldQueue{ 使用 Queueable;

..... .... ... }

3.That就这样

接口&特征路径: 使用 Illuminate\Contracts\Queue\ShouldQueue; 使用 Illuminate\Bus\Queueable;

请同时查看文档: https://laravel.com/docs/5.7/notifications#queueing-notifications

我的解决方案适用于您是否要在控制器中手动注册用户。 Laravel 已经创建了 Registered 事件及其侦听器 SendEmailVerificationNotification。

-首先在应用程序中配置队列 在 .env 文件更新 QUEUE_CONNECTION=database。 有关更多队列文档,请阅读 https://laravel.com/docs/6.x/queues

  • 发布队列 table php artisan queue:table

  • php artisan migrate

  • php artisan make:job EmailVerificationJob

  • 在EmailVerificationJob.php中添加public变量

    public $用户;

  • 在EmailVerificationJob.php构造函数中

    public 函数 __construct(用户 $user) { $this->user = $user; }

  • 在EmailVerificationJob.php处理函数写入event(new Registered($this->user)).

  • 如果用户创建成功,请在您的控制器中添加此代码以使作业正常工作。

    EmailVerificationJob::dispatch($user) ->延迟(现在()->添加秒数(5)); 这里作业延迟 5 秒。

  • 最后你必须启动队列工作者php artisan queue:work --tries=3。这里的 tries 表示队列应该尝试作业的次数。

更新#1

我在 Laravel 8.

中使用的这个解决方案

首先创建 SendEmailVerificationNotification 通知class

php artisan make:notification SendEmailVerificationNotification

app/Notifications/SendEmailVerificationNotification.php文件内容就是这个。在这里我们将扩展 Laravel 默认 SendEmailVerificationNotification class 并实现 should queue

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class SendEmailVerificationNotification extends \Illuminate\Auth\Listeners\SendEmailVerificationNotification implements ShouldQueue
{
    use Queueable;
}

最后一步是编辑 EventServiceProvider class $listen 数组。注释掉注册事件的默认通知并添加我们创建的自定义通知。

use App\Notifications\SendEmailVerificationNotification as QueuedSendEmailVerificationNotification;
use Illuminate\Auth\Events\Registered;
//use Illuminate\Auth\Listeners\SendEmailVerificationNotification;

protected $listen = [
        Registered::class => [
//            SendEmailVerificationNotification::class,
            QueuedSendEmailVerificationNotification::class
        ],

];