Laravel - 从扩展类覆盖父构造函数

时间:2014-10-29 18:02:33

标签: php laravel laravel-4

我正在从一个包扩展一个控制器,所以我可以编辑它,避免在使用composer更新时丢失更改。到目前为止一切正常但我的构造函数存在问题。

我原来的课有这个:

class UserRegisterService
{


    public function __construct(UserSignupValidator $v = null)
    {
        //unrelated stuff here
        Event::listen('service.activated',
                      'Jacopo\Authentication\Services\UserRegisterService@sendActivationEmailToClient');
    }
}

扩展控制器是:

use Jacopo\Authentication\Services\UserRegisterService;
use Jacopo\Authentication\Validators\UserSignupValidator;


class CustomUserRegisterService extends UserRegisterService
{

    public function __construct(UserSignupValidator $v = null)
    {
        //unrelated stuff here
        Event::listen('service.activated',
                      'CustomUserRegisterService@sendActivationEmailToClient');
    }

我的基本相同,我的扩展类的更改是在CustomUserRegisterService @ sendActivationEmailToClient内部(基本上我想发送一个与原始控制器不同的电子邮件,使用mandrill和自定义模板)。

事件正在触发并且正在调用这两个函数,因此在激活用户时会收到重复的电子邮件(在这种情况下是事件)。我只想要调用我的自定义类的构造函数,而另一个需要被忽略。

这可能吗?

编辑:正如评论中所建议的,我评论了原始构建的Event :: listen并解决了问题,只发送了一封电子邮件。但是,当然这并没有解决一旦我更新它就会被取消注释的问题。

添加return false;在CustomUserRegisterService @ sendActivationEmailToClient结尾处也没有工作,只是在构造函数中注释了事件就行了。

1 个答案:

答案 0 :(得分:1)

只要你不在CustomUserRegisterService类中调用parent :: __ construct(),就不会执行UserRegisterService __construct。但是你必须在CustomUserRegisterService类__constructor中的UserRegisterService中实现“不相关的东西”。

class A {
	public function __construct($v = "")
	{
		echo "A's constructor";
	}
}


class B extends A{
	public function __construct()
	{
        //parent::__construct();

		echo "B's constructor";
	}
}


$b = new B();

输出:B的构造函数

至于你的例子

好的,这是一个想法,但首先请检查您是否在代码中的某处实例化UserRegisterService。如果是这样,你必须使它成为单身人士。在UserRegisterService类Event :: listent中它说当它触发'service.activated'时运行UserRegisterService的sendActivationEmailToClient。因此,每当触发'service.activated'系统实例化UserRegisterService的对象时,就运行sendActivationEmailToClient函数。现在的问题是,当系统创建UserRegisterService实例时,它运行构造函数。这意味着它向事件池添加了另一个侦听器。 IMO您需要做的是使用户laravel不会多次加载(实例化)UserRegisterService或CustomUserRegisterService。

例如:

//AClass.php in model folder

class AClass
{

    public function __construct($v = "")
    {
        echo "A's constructor <br />";
        
        Event::listen('a.run', 'A@hi');
    }

    public static function hi()
    {
         echo "Its me, A's event <br />";
    }
    

}

//BClass.php in model folder

class BClass extends AClass
{

    public function __construct()
    {
        //parent::__construct();
        echo "B's constructor <br />";
        
        Event::listen('a.run', 'BClass@hi');
        
    }

    public static function hi()
    {
        echo "Its me, B's event <br />";
    }

}




//in app/routes.php or in your service provider

App::singleton('ObjB', function(){
    return new BClass();
});

APP::bind('BClass', function(){
    return App::make('ObjB');
});


//test the events
Route::get('/',  function(){
    $b = App::make('ObjB');
    
    echo "1st event trigger ------------ <br/>";
    Event::fire('a.run');
    
    echo "2nd event trigger ------------ <br/>";
    Event::fire('a.run');
    
    echo "3rd event trigger ------------ <br/>";
    Event::fire('a.run');
});

我希望这会对你有所帮助。我正在laravel 4.2测试这个,它的工作从我这里来。让我知道你的结果。感谢