You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在User模型外部重写sendPasswordResetNotification方法?

解决方法

针对你需要将密码重置通知方法移出公共User模型的需求,这里提供两种可行方案:

方案一:用自定义Trait封装逻辑(推荐,操作简单)

如果公共项目的User模型允许添加Trait引用,这是最直接的方式:

  1. 创建自定义Trait
    在项目中新建一个Trait文件,比如app/Traits/CustomPasswordResetNotification.php,把原来的通知逻辑移进去:
<?php

namespace App\Traits;

use App\Notifications\ResetPasswordNotification;

trait CustomPasswordResetNotification
{
    /**
     * 发送密码重置通知
     *
     * @param  string  $token
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new ResetPasswordNotification($token));
    }
}
  1. 在User模型中引入Trait
    修改公共项目的User模型,引入自定义Trait(注意要放在CanResetPassword之后,PHP会优先使用后引入Trait的同名方法):
// User.php
use Illuminate\Auth\Passwords\CanResetPassword;
use App\Traits\CustomPasswordResetNotification;

class User extends Authenticatable
{
    use CanResetPassword, CustomPasswordResetNotification;
    
    // 移除原来写在User模型里的sendPasswordResetNotification方法
    // ... 其他原有代码
}

这样既把逻辑移到了外部文件,又确保不会使用CanResetPassword中可能存在的同名方法(实际Laravel原生的CanResetPassword没有这个方法,这里是为了满足你排除原trait方法的需求)。

方案二:事件监听+重写PasswordBroker(无侵入修改User模型)

如果完全不能修改公共的User模型,可以通过Laravel的事件系统和自定义PasswordBroker来实现:

  1. 创建事件监听器
    新建监听器app/Listeners/SendPasswordResetNotification.php:
<?php

namespace App\Listeners;

use Illuminate\Auth\Events\PasswordResetRequested;
use App\Notifications\ResetPasswordNotification;

class SendPasswordResetNotification
{
    public function handle(PasswordResetRequested $event)
    {
        // 发送自定义密码重置通知
        $event->user->notify(new ResetPasswordNotification($event->token));
    }
}
  1. 注册事件监听
    在app/Providers/EventServiceProvider.php中添加事件与监听器的绑定:
protected $listen = [
    \Illuminate\Auth\Events\PasswordResetRequested::class => [
        \App\Listeners\SendPasswordResetNotification::class,
    ],
];
  1. 重写PasswordBroker
    为了避免User模型中原有的sendPasswordResetNotification方法被调用,需要自定义PasswordBroker替换原生实现,新建app/Auth/Passwords/PasswordBroker.php:
<?php

namespace App\Auth\Passwords;

use Illuminate\Auth\Passwords\PasswordBroker as BasePasswordBroker;

class PasswordBroker extends BasePasswordBroker
{
    public function sendResetLink(array $credentials)
    {
        $user = $this->getUser($credentials);

        if (is_null($user)) {
            return static::INVALID_USER;
        }

        // 只触发事件,不调用模型的sendPasswordResetNotification方法
        $this->events->dispatch(new \Illuminate\Auth\Events\PasswordResetRequested($user, $this->createToken($user)));

        return static::RESET_LINK_SENT;
    }
}
  1. 注册自定义PasswordBroker
    在app/Providers/AuthServiceProvider.php的boot方法中绑定自定义实现:
use App\Auth\Passwords\PasswordBroker;

public function boot()
{
    $this->app->bind('auth.password', function ($app) {
        return new PasswordBroker(
            $app['auth.password.broker.database'],
            $app['auth']->createUserProvider(),
            $app['url'],
            $app['mailer'],
            $app['events'],
            config('auth.passwords.users.email')
        );
    });
}

内容的提问来源于stack exchange,提问作者Ayşe Taş

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 14:35:50