如何解决PHP中的钻石问题?
How to resolve the diamond issue in PHP?
我已经搜索了钻石问题的解决方案,但我找到的唯一一个是使用 traits,我不能在我的情况下使用它,所以我在这里问问是否有人有替代解决方案。
我有一个基础 class Controller
(我不能改变这个 class)并且有两个子class SecurityController
和 DevController
.这些子 class 中的每一个都引入了一些方法,这些方法也在基 class 中使用了方法。然后我有一个最终的 class ApplicationController
,理想情况下,它会扩展 SecurityController
和 DevController
。当然,这在 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);
我已经搜索了钻石问题的解决方案,但我找到的唯一一个是使用 traits,我不能在我的情况下使用它,所以我在这里问问是否有人有替代解决方案。
我有一个基础 class Controller
(我不能改变这个 class)并且有两个子class SecurityController
和 DevController
.这些子 class 中的每一个都引入了一些方法,这些方法也在基 class 中使用了方法。然后我有一个最终的 class ApplicationController
,理想情况下,它会扩展 SecurityController
和 DevController
。当然,这在 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);