如何使用laravel 5中的队列通过电子邮件发送密码重置链接

Fok*_*est 10 email queue laravel-5 laravel-5.1

我正在使用laravel的ResetsPasswords特性来实现密码重置.我想要实现的是使用队列发送电子邮件.通过代码挖掘我在函数postEmail()中找到了以下行:

$response = Password::sendResetLink($request->only('email'), function (Message $message) {
            $message->subject($this->getEmailSubject());
        }); 
Run Code Online (Sandbox Code Playgroud)

进一步挖掘我注意到sendResetLink()函数是在PasswordBroker类中实现的,而PasswordBroker类又调用函数emailResetLink().emailResetLink函数返回以下内容:

return $this->mailer->send($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
            $m->to($user->getEmailForPasswordReset());
Run Code Online (Sandbox Code Playgroud)

我可以简单地mailer->send改为mailer->queue.如果不修改这个非项目文件,它们是更好的方法吗?

fak*_*eta 19

我知道这已经得到了解答,但我找到了排队密码重置通知的另一种方法,我发现这更简单.我在Laravel 5.3上测试过它.

默认情况下,密码重置通知由Illuminate\Auth\Notifications\ResetPassword类实现.此类UsersendPasswordResetNotification方法中的模型中实例化并传递给trait notify方法Illuminate\Notifications\Notifiable.

因此,要对密码重置通知进行排队,您只需创建新的ResetPassword通知类,artisan make:notification ResetPassword并将其替换为以下代码:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification;

class ResetPassword extends ResetPasswordNotification implements ShouldQueue
{
    use Queueable;
}
Run Code Online (Sandbox Code Playgroud)

现在只需sendPasswordResetNotification在您的App\User类中覆盖方法:

<?php

...
use App\Notifications\ResetPassword as ResetPasswordNotification;
...    

/**
 * Send the password reset notification.
 *
 * @param  string  $token
 * @return void
 */
public function sendPasswordResetNotification($token)
{
    $this->notify(new ResetPasswordNotification($token));
}
Run Code Online (Sandbox Code Playgroud)


mar*_*den 4

这就是 Laravel 容器可以发挥作用的地方。如果您不喜欢核心组件的功能,那么您可以轻松地覆盖它。

首先,您需要创建自己的PasswordBroker:

namespace App\Auth\Passwords;

use Illuminate\Auth\Passwords\PasswordBroker as IlluminatePasswordBroker;

class PasswordBroker extends IlluminatePasswordBroker
{

    public function emailResetLink()
    {
        $view = $this->emailView;

        return $this->mailer->queue($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
            $m->to($user->getEmailForPasswordReset());
            if (! is_null($callback)) {
                call_user_func($callback, $m, $user, $token);
            }
        });
    }

}
Run Code Online (Sandbox Code Playgroud)

如果您想将名称空间放置在应用程序的其他位置,请将名称空间更改为您想要的任何名称。

由于注册服务的服务提供者是延迟服务提供者,因此您需要创建自己的提供者来替换它。也许最简单的方法是Illuminate\Auth\Passwords\PasswordResetServiceProvider使用如下所示的扩展:

namespace App\Providers;

use App\Auth\Passwords\PasswordBroker;

class PasswordResetServiceProvider extends \Illuminate\Auth\Passwords\PasswordResetServiceProvider
{

    protected function registerPasswordBroker()
    {
        $this->app->singleton('auth.password', function ($app) {
            $tokens = $app['auth.password.tokens'];

            $users = $app['auth']->driver()->getProvider();

            $view = $app['config']['auth.password.email'];

            return new PasswordBroker(
                $tokens, $users, $app['mailer'], $view
            );
        });
    }

}
Run Code Online (Sandbox Code Playgroud)

最后在您的config/app.php文件中删除Illuminate\Auth\Passwords\PasswordResetServiceProvider::class并添加App\Providers\PasswordResetServiceProvider::class到您的'providers'数组中。

Laravel 现在将使用您的 PasswordBroker 实现,而不是现有框架实现,您不必担心修改框架代码。