6

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

有没有办法通过队列发送电子邮件验证电子邮件而无需在 Laravel 5.7 中重写整个电子邮件验证?

4

4 回答 4

44

没有内置方式,但您可以通过扩展和覆盖轻松完成。

首先,创建一个扩展内置通知的新通知,并且还实现了 ShouldQueue 协定(以启用排队)。以下类假设您在以下位置创建通知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.
}

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

public function sendEmailVerificationNotification()
{
    $this->notify(new \App\Notifications\VerifyEmailQueued);
}
于 2018-10-04T12:47:34.567 回答
11

是的!这是可能的。要做到这一点,你将不得不重写sendEmailVerificationNotification你的App\User. 此方法由Illuminate\Auth\MustVerfiyEmailtrait 提供。该方法通过发送通知类中定义的电子邮件来sendEmailVerificationNotification通知创建者。userIlluminate\Auth\Notifications\VerifyEmail

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

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

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

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

$this表示已创建user,并且App\Jobs\VerififyEmail作业(您将创建的)将接收传递给dispatch其的所有参数__construct

的代码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);
    }
}
于 2018-10-04T11:48:56.917 回答
3

我的解决方案是如果您要在控制器中手动注册用户。Laravel 已经创建了 Registered 事件和它的监听器 SendEmailVerificationNotification。

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

  • 通过发布队列表php artisan queue:table

  • php artisan migrate

  • php artisan make:job EmailVerificationJob

  • 在 EmailVerificationJob.php 添加公共变量

    公共$用户;

  • 在 EmailVerificationJob.php 构造函数中

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

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

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

    EmailVerificationJob::dispatch($user) ->delay(now()->addSeconds(5)); 这里作业延迟 5 秒。

  • 最后,您必须启动 queue worker php artisan queue:work --tries=3。这里的尝试意味着队列应该尝试多少次工作。

更新#1

我在 Laravel 8 中使用的这个解决方案。

首先创建 SendEmailVerificationNotification 通知类

php artisan make:notification SendEmailVerificationNotification

app/Notifications/SendEmailVerificationNotification.php 文件内容将是这一项。这里我们将扩展 Laravel 默认的 SendEmailVerificationNotification 类并实现应该队列

<?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 类 $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
        ],

];

于 2019-10-30T11:55:57.433 回答
-4

解决方案非常简单:

Steps:

  1. 配置队列驱动程序

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

  3. 实现“ShouldQueue”接口并在上述类上添加一个特征“Queueable”,即“VerifyEmail”,如下所示:

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

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

3.就是这样

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

请也检查文档: https ://laravel.com/docs/5.7/notifications#queueing-notifications

于 2018-11-26T19:03:53.390 回答