PHP trait method conflicts: trait "inheritance" and trait hierarchies

class, multiple-inheritance, php, traits

Solution

So the unofficial "official" answer is:

You can do it without aliasing, insteadof or anything! But not yet...

I upgraded from 5.5.1 to 5.5.6 but it was all in vain. I will update this answer when the fix becomes available. Interesting to note is that you can call trait static functions directly. The following example works:

trait TheErrorOfYourWays{
    public static function booboo($thisTrait){
        echo 'You had a booboo :( in '.$thisTrait.'<br>';
    }
}

trait SpectacularStuff1 {
    public function boobooTest1(){
        TheErrorOfYourWays::booboo(__TRAIT__);
    }
}

trait SpectacularStuff2 {
    public function boobooTest2(){
        TheErrorOfYourWays::booboo(__TRAIT__);
    }
}

class DoSomethingSpectacular {
    use SpectacularStuff1, SpectacularStuff2;
}

$boobooAChoo = new DoSomethingSpectacular();
$boobooAChoo->boobooTest1(); // You had a booboo :( in SpectacularStuff1
$boobooAChoo->boobooTest2(); // You had a booboo :( in SpectacularStuff2

Yes, yes, you can also do that with a class but classes are soooo last season.

Problem

UPDATE: I am not alone in my pondering on this issue and it seems it is indeed a bug. See here. The day it is fixed is going to be a fantastic day! :) This started out as `I love PHP traits! I'm going to use them everywhere! ^_^` and now it has turned into a `Thought Exercise / Learning Experience >_<`. Consider the following example: ``` trait TheErrorOfYourWays{ public function booboo(){ echo 'You had a booboo :('; } } trait SpectacularStuff1 { use TheErrorOfYourWays; } trait SpectacularStuff2 { use TheErrorOfYourWays; } class DoSomethingSpectacular { use SpectacularStuff1, SpectacularStuff2; } ``` This results in (obviously not so obviously): Fatal error: Trait method booboo has not been applied, because there are collisions with other trait methods on DoSomethingSpectacular. So my question: How do I resolve method conflicts in traits? Is it possible to achieve overlapping trait "inheritance"? If so, what is the "right" way to do this? Why I want to do this: - I want to create self contained traits and classes (mix and match style). If it is at all possible, I want to say "use" and then magic stuff must happen. No having to scratch my head and think, "Now what namespace was that trait in again?", etc, etc. - No having to edit classes and traits on the fly when I do something "adventurous" and discover I have inadvertently created a conflict. - Seemed like a good idea at the time. What I have tried: - The PHP Manual. - The Google. - SO including this question -> Not the correct answer for this scenario. - Found this but I am using PHP version 5.5.1. It's fixed, right? Right? A fantastic array of "as", aliases, even insteadof, in different places, times, universes, etc. Including, but not limited to: ``` trait SpectacularStuff1 { use TheErrorOfYourWays{ TheErrorOfYourWays::booboo as booboo1; } } trait SpectacularStuff2 { use TheErrorOfYourWays{ TheErrorOfYourWays::booboo as booboo2; } } class DoSomethingSpectacular { use SpectacularStuff1, SpectacularStuff2 { /* Tried separately, but included here for brevity's sake */ SpectacularStuff1::booboo as booboo3; SpectacularStuff2::booboo as booboo4; } } ``` AND ``` use TheErrorOfYourWays as Erroneous1; trait SpectacularStuff1 { use Erroneous1{ Erroneous1::booboo as booboo1; } } use TheErrorOfYourWays as Erroneous2; trait SpectacularStuff2 { use Erroneous2{ Erroneous2::booboo as booboo2; } } ``` I understand that: - I can change TheErrorOfYourWays to a class and make booboo() static but I would like to learn about this specific trait behaviour. - I can remove TheErrorOfYourWays from the traits and use it in the class, but that's hardly "self-contained" then. Everytime I use the traits I have to remember to use TheErrorOfYourWays in the class even if I don't call booboo() directly from the class. Sounds dangerous. - I have probably made some rookie syntax error or failed to understand aliasing on a profound level. If so, please... explain... slowly... - There is probably a better way to do this. If so, please... explain... slowly... - I may be prematurely enthusiastic and PHP doesn't do this yet. Let me down gently. Thanks!

Original source