关于重写 sendResetResponse() 方法的trait加载机制 
                            
                                                    
                        
                    
                    
  
                    
                    Trait 与类的冲突处理
当存在同名方法时,当前类的方法会覆盖 Trait 中的方法,而 Trait 中的方法会覆盖父类的方法。
例子:
目录结构如下:
OOP
--traits
    --test
        helloTrait.php
myHelloWord.phphelloTrait.php代码如下:
<?php
namespace OOP\traits\test;
trait helloTrait
{
    public function hello(){
        echo 'this is helloTrait';
    }
}- 当myHelloWord类中没有声明hello()方法时:
代码如下:
<?php
require './vendor/autoload.php';
use OOP\traits\test\helloTrait;
class myHelloWorld
{
    use helloTrait;
    public function sayHello(){
        // 调用hello方法。
        $this->hello();
    }
}
$obj = new myHelloWorld();
$obj->sayHello();毫无疑问,输出的是this is helloTrait,也就是说调用的是trait中的hello()方法。
- 当myHelloWord类中声明了hello()方法时:
代码如下:
<?php
require './vendor/autoload.php';
use OOP\traits\test\helloTrait;
class myHelloWorld
{
    use helloTrait;
    public function sayHello(){
        // 调用hello方法。
        $this->hello();
    }
    public function hello(){
        echo 'this is myHelloWorld';
    }
}
$obj = new myHelloWorld();
$obj->sayHello();输出的是:this is myHelloWorld。也就是说调用的是myHelloWorld类中的方法。也就是说当前类的hello()方法覆盖了trait中的hello()方法。
正如文章开头所言:
当类与trait存在同名方法时,当前类的方法会覆盖 Trait 中的方法。
回到教程中重写 sendResetResponse() 方法的问题
- 先看更新密码的路由:Route::post('password/reset', 'Auth\ResetPasswordController@reset')->name('password.update');

- 当我们点击重置密码的时候会调用ResetPasswordController的reset()方法。我们先看一下ResetPasswordController的码源:
 发现<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ResetsPasswords; use Illuminate\Http\Request; class ResetPasswordController extends Controller { use ResetsPasswords; protected $redirectTo = '/'; public function __construct() { $this->middleware('guest'); } }ResetPasswordController类中没有reset()方法,但是发现使用了ResetsPasswordstrait。根据use Illuminate\Foundation\Auth\ResetsPasswords;和教程得知:该路由调用的是ResetsPasswordstrait中的reset()方法。我们来看一下ResetsPasswordstrait中的reset()方法的返回值:
 根据注释我们得知public function reset(Request $request) { ... // 如果重置成功,我们会调用 sendResetResponse 方法重定向到程序主页上, // 失败的话调用 sendResetFailedResponse 返回并附带错误信息 return $response == Password::PASSWORD_RESET ? $this->sendResetResponse($request, $response) : $this->sendResetFailedResponse($request, $response); }如果重置成功,我们会调用 sendResetResponse 方法重定向到程序主页上。
 回到本节的问题:重置密码成功后没有反馈。也就是说ResetsPasswordstrait中的sendResetResponse()方法并没有达到预期的效果。但是ResetsPasswordstrait是laravel框架自带的,最好不要去动它。更好的解决办法是覆盖trait中的sendResetResponse()方法。
具体的解决办法
利用Trait 与类的冲突处理。即在ResetPasswordController类中声明sendResetResponse()方法。
<?php
...
class ResetPasswordController extends Controller
{
    ...
    protected function sendResetResponse(Request $request, $response)
    {
        session()->flash('success', '密码更新成功,您已成功登录!');
        return redirect($this->redirectPath());
    }
} 
           
         
             
             
             
                     
                     
           
           关于 LearnKu
                关于 LearnKu
               
                     
                     
                     粤公网安备 44030502004330号
 粤公网安备 44030502004330号 
 
推荐文章: