如何解决PHP中的菱形问题? [英] How to resolve the diamond issue in PHP?

查看:112
本文介绍了如何解决PHP中的菱形问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找解决钻石问题的方法,但我发现的唯一方法是使用

I have searched for solutions to the diamond problem but the only one I have found is using traits which I can't use in my case, so I'm asking here to see if anyone has an alternative solution.

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

I have a base class Controller (I cannot change this class) and have two subclasses SecurityController and DevController. Each of these subclasses introduces methods which also use methods inside the base class. I then have a final class ApplicationController which, ideally, would extend both SecurityController and DevController. Of course, this isn't possible in PHP (single inheritance only).

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

So my question becomes - what would be the best way to resolve this? I came across traits but then realised that doesn't work as the 2 subclasses (which I thought might suit traits) both need to extend Controller to access methods inside it. The only other alternative I can see is forcing SecurityController to extend DevController (or vice versa). Although this works it is not ideal as these two classes come from separate modules which I was hoping to create as a drop in and use as is type of plugin.

这篇关于代码审查的帖子看起来很有希望.不过,还有一种替代方法会很好-我觉得在尝试改进该代码时可能会引入错误.

This post on code review looks promising. An alternative would be good though - I feel I'm likely to introduce errors when trying to improve upon that code.

有关解决方案的说明

公认的答案仍然是我发现一般可以解决此问题的最佳方法.但是,在这种情况下,我可以使用特征.我在SecurityController中有一个称为beforeExecute($dispatcher)的方法-通过将其更改为beforeExecuteTrait($controller, $dispatcher)并使SecurityController为特征,然后使ApplicationController扩展Controller,使用SecurityController并在ApplicationController中添加一个方法为

The accepted answer is still the best way I have found to resolve this issue in general. However, in this case I was able to use traits. I had a method in SecurityController called beforeExecute($dispatcher) - by changing it to beforeExecuteTrait($controller, $dispatcher) and making SecurityController a trait then having ApplicationController extend Controller, use SecurityController and adding a method in ApplicationController as

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

并通过对DevController应用相同的逻辑,我达到了预期的行为.

and by applying the same logic to DevController I achieved the desired behaviour.

推荐答案

听起来您可以从中受益依赖项注入.换句话说,您将实例化其他类,然后将这些实例注入您的主类中供您使用.这样可以避免PHP中的继承问题.

It sounds like you could benefit from dependency injection. In other words, you would instantiate the other classes and then inject those instances into your main class for you to use. This avoids any messes with inheritance in 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);

这篇关于如何解决PHP中的菱形问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆