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

How to resolve the diamond issue in PHP?

我已经搜索了钻石问题的解决方案,但我找到的唯一一个是使用 traits,我不能在我的情况下使用它,所以我在这里问问是否有人有替代解决方案。

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

所以我的问题变成了 - 解决这个问题的最佳方法是什么?我遇到了 traits 但后来意识到这不起作用,因为 2 个 subclasses(我认为可能适合 traits)都需要扩展 Controller 到访问其中的方法。我能看到的唯一其他选择是强制 SecurityController 扩展 DevController(反之亦然)。尽管这可行,但并不理想,因为这两个 classes 来自不同的模块,我希望将其创建为 插入并按原样使用 类型的插件。

This post 代码审查看起来很有希望。不过,替代方案会很好 - 我觉得在尝试改进该代码时可能会引入错误。

解法注意事项

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

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

通过对 DevController 应用相同的逻辑,我实现了预期的行为。

听起来您可以从 dependency injection 中受益。换句话说,您将实例化其他 classes,然后将这些实例注入到您的主 class 中供您使用。这避免了 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);