在Laravel中扩展多个类

时间:2014-02-22 16:30:04

标签: php laravel extends revisionable

我陷入困境,因为Php本身不允许扩展多个类,我使用laravel模型与数据交互,并希望使用2个不同的包来扩展它的功能。

我正在尝试使用Ardent验证程序和Revisionable来维护更新历史记录,但我不知道如何在我的模型中扩展这两个类。

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

我最近投入大量精力制作可修改的特性。

所以你可以use,就像这样:

class User extends Ardent {
    use \Venturecraft\Revisionable\RevisionableTrait;
}

它目前在开发分支中,但在它合并到maser之前我会喜欢一些帮助测试:

https://github.com/VentureCraft/revisionable/issues/36

[编辑] 现在位于主分支中,可供公众使用。

答案 1 :(得分:0)

正如您所说,PHP不支持多重继承,因此您没有很多选项。尽管很丑陋,但您可能不得不求助于使用__call()魔术方法的this之类的东西。

答案 2 :(得分:0)

如您所知,PHP不支持多重继承,遗憾的是,这是一个PHP缺陷,也是由热心和可修改的包开发人员创建的问题。以Sentry为例,你可以使用你想要的任何Eloquent实现,你只需在config.php中设置你需要的那个。不幸的是,Laravel的手被束缚,因为它是所有这些包的基类。在我看来。

所以你有一些选择:

1)在两个软件包git存储库上都存在问题,并希望其中一个更改为支持继承,不仅来自\ Eloquent,还有任何用户的类,扩展了Eloquent Model抽象类。

您甚至可以更改其中一个软件包的代码,并向存储库发送拉取请求。如果这是一个很好的改变你可能会看到它发生。

2)使用存储库模式,通过创建一个从Eloquent扩展的类,将两个包作为依赖项,并在其中,从这些包中调用您需要的任何内容。这不会是小菜一碟,因为Eloquent是一个复杂的类,如果你使用__call(),你将必须映射你需要转发到你的包的所有方法,所以你不会冒险破坏Eloquent的自己动态调用:

use Ardent;
use Revisionable;

class User extends Eloquent {

    private $ardent;

    privave $revisionable;

    public function __construct(Ardent $ardent, Revisionable $revisionable)
    {
        $this->ardent = $ardent;

        $this->revisionable = $revisionable;
    }

    public function doWhatever() 
    {
        return $this->ardent->do();
    }

    public function __call($name, $arguments)
    {
        if($this->isArdentMethod($name))
        {
            return call_user_func_array(array($this->ardent,$name), $arguments);
        }
        else
        if($this->isRevisionableMethod($name))
        {
            return call_user_func_array(array($this->revisionable,$name), $arguments);
        }
        else
        {
            return parent::__call($name, $arguments);
        }
    }
}

请注意此调用

return parent::__call($name, $arguments);

确保您的所有通话都被重定向到您的Eloquent类,如果它们不打算由其他人执行。

事实上你甚至可以选择其中一个,比如Ardent作为你的主要班级:

class User extends Ardent {}

并且只能作为依赖项进行修订:

public function __construct(Revisionable $revisionable)

然后转发对注入的依赖项的可修改调用。因为,最后,这些类都是Eloquent,你可以有许多指向同一个表的Eloquent模型。

如果你查看可修改的源代码,那么你真正需要考虑的唯一电话是save(),因为它会从Eloquent覆盖它,所有其他你只能调用Ardent的。

我知道这听起来有点太多了,但它是可行的。