How to resolve the diamond issue in PHP?

怎甘沉沦 提交于 2020-01-16 00:06:40

问题


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.

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).

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.

Note about the solution

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);
}

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


回答1:


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);


来源:https://stackoverflow.com/questions/32188850/how-to-resolve-the-diamond-issue-in-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!