如何解决PHP中的钻石问题?

时间:2015-08-24 18:07:47

标签: php inheritance diamond-problem

我已经搜索了钻石问题的解决方案,但我找到的唯一一个是使用traits我无法在我的情况下使用,所以我在这里询问是否有人有另一种解决方案。

我有一个基类Controller(我无法更改此类)并且有两个子类SecurityControllerDevController。这些子类中的每一个都引入了也使用基类内部方法的方法。然后我有一个最后的课程ApplicationController,理想情况下,它会扩展SecurityControllerDevController。当然,这在PHP中是不可能的(仅限单继承)。

所以我的问题变成了 - 解决这个问题的最佳方法是什么?我遇到了 traits ,但后来意识到它不能作为2个子类(我认为可能适合特征)工作,它们都需要扩展Controller来访问其中的方法。我能看到的唯一其他选择是强制SecurityController扩展DevController(反之亦然)。虽然这很有效,但它并不理想,因为这两个类来自单独的模块,我希望创建它们作为插入并使用类型的插件。

代码审查的

This post看起来很有希望。另一种方法是好的 - 我觉得在尝试改进代码时我可能会引入错误。

关于解决方案的说明

接受的答案仍然是我发现解决此问题的最佳方法。但是,在这种情况下,我能够使用特征。我在SecurityController中有一个名为beforeExecute($dispatcher)的方法 - 将其更改为beforeExecuteTrait($controller, $dispatcher)并使SecurityController为特征,然后ApplicationController延长Controller,请使用SecurityController并在ApplicationController中添加方法

public function beforeExecute($dispatcher)
{
    return $this->beforeExecuteTrait($this, $dispatcher);
}

并通过对DevController应用相同的逻辑,我实现了理想的行为。

1 个答案:

答案 0 :(得分:2)

听起来你可以从dependency injection中受益。换句话说,您将实例化其他类,然后将这些实例注入主类中供您使用。这避免了PHP中继承的任何混乱。

class A extends B {

}

class C {
    /** @var \A */
    protected $classa;

    public function __construct(\A $class) {
         $this->classa = $class;
    }
}

$a = new \A();
$c = new \C($a);