Search code examples
phpinheritanceconstructormultiple-inheritancetraits

Multiple inheritance + Multi-Level inheritance in PHP: Is there a pattern or possibility to solve constructor inheritance?


Have a look at the following example:

class A {
    protected $a;
    public function __construct() {
        $this->a = "foo";
    }
}

trait Q {
    protected $q;
    public function __construct() {
        $this->q = "happy";
    }
}

class B extends A {
    use Q;
    protected $b;
    public function __construct() {
        $this->b = "bar";
    }
}

trait X {
    protected $x;
    public function __construct() {
        $this->x = "lorem";
    }
}

class C extends B {
    use X;
    protected $c;
    public function __construct() {
        $this->c = "sure";
    }

    public function giveMeEverything() {
        echo $this->a." ".$this->b." ".$this->c." ".$this->x." ".$this->q;
    }
}

$c = new C();
$c->giveMeEverything();

This works just fine - the output is:

sure

The thing is that I want all classes and and traits within the tree to initialize their member variables. Desired output:

foobarsureloremhappy

It must not be solved with constructors! I just want the member variables to be populated on initialization, but I still had no good idea how to solve this. In a real world example this is more complex, therefore please do not $a = "foo"; just within the variables declaration.


Solution

  • The problem is that traits cannot be instantiated so __construct() is kind of meaningless.

    The best approach is to initialize your member variables using the class constructor; that's why constructors exist.

    If you want to initialize some members that are declared in a trait, then have a trait function and call it in the appropriate class constructor, example:

    trait Q {
        protected $a;
        public function initQ() { $this->a = "whatever"; }
    }
    
    class MyClass {
        use Q;
    
        public function __construct() {
            $this->initQ();
        }
    }