15

I wan't to execute constructor in my trait (or another method while trait is used). Is it possible?

trait test{
    public function __construct()
    {
        echo 'test';
    }
}

class myClass{
    use test;
    public function __construct(){
        echo 'myClass';
    }
}
new myClass();
Bolek Lolek
  • 577
  • 2
  • 9
  • 22
  • 1
    Not if you override the trait constructor code with a class constructor code; traits aren't inherited like extends.... but you could create an "intermediate" class that uses the trait, and then extend `myClass` from that "intermediate" and then call `parent::__construct()` - [Demo](https://3v4l.org/8kVtU) – Mark Baker Dec 18 '17 at 10:31

2 Answers2

24

Try it like this (test):

trait test{
    public function __construct()
    {
        echo 'test';
    }
}

class myClass{
    use test {
        test::__construct as private __tConstruct;
    }
    public function __construct(){
        $this->__tConstruct();
    }
}
new myClass();
Claudio
  • 5,078
  • 1
  • 22
  • 33
  • 1
    @Garre I personally don't see it as hacky as long as you use it following the main goal of traits ["A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies"](https://www.php.net/manual/en/language.oop5.traits.php). – Claudio Apr 26 '19 at 16:05
  • 2
    Similar answer here: https://stackoverflow.com/a/12583603/470749 – Ryan Jan 29 '20 at 19:37
  • Wouldn't it make more sense just to create a function to work as the construct in the trait? Perhaps named with the name of the trait? e.g. public function __testConstruct() {} – Scott Jul 13 '21 at 15:02
0

I'm still not finding a documented best practice for this, so I'm following the trait boot pattern from Laravel with a __constructMyTraitName method on the trait, and calling it from the model constructor. This seems cleaner than the "use" alias.

trait MyTrait {
    public function __constructMyTrait($attributes)
    {
        // Trait constructor logic here
    }
}

Then in my model:

    use MyTrait;

    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
        $this->__constructMyTrait($attributes);
    }
stephenr85
  • 151
  • 1
  • 4