ymakux
ymakux

Reputation: 3485

May I use properties from a parent class in a trait?

Is it OK to use properties/methods from parent classes in trait methods?

This code works, but is it good practice?

class Child extends Base{

  use ExampleTrait;

  public function __construct(){
     parent::__construct();
  }

  public function someMethod(){
    traitMethod();
  }

}

trait ExampleTrait{
  protected function traitMethod(){
    // Uses  $this->model from Base class
    $this->model->doSomething();
  }
}

Upvotes: 14

Views: 12365

Answers (2)

tecdoc ukr net
tecdoc ukr net

Reputation: 134

A Trait intended to group functionality in a fine-grained and consistent way. It is not possible to instantiate a Trait on its own. It is an addition to traditional inheritance and enables horizontal composition of behavior; that is, the application of class members without requiring inheritance. {Official PHP documentation}

Methods defined in traits can access methods and properties of the class they're used in, including private ones!!!

In other words, Trait is an extension of the code (addition)! So using properties/methods from bases/parent classes in trait is not bad practice! Traits were designed for this.

Upvotes: 1

Joe
Joe

Reputation: 1696

I don't think it's good practice.

Instead you could have a method to fetch your model object, and have that method as an abstract signature in you trait:

trait ExampleTrait {
    abstract protected function _getModel();

    protected function traitMethod() {
        $this->_getModel()->doSomething();
    }
}

class Base {
    protected $_model;

    protected function _getModel() {
        return $this->_model;
    }
}

class Child extends Base {
    use ExampleTrait;

    public function someMethod() {
        $this->traitMethod();
    }
}

Or pass your model as a parameter to your trait method:

trait ExampleTrait {
    protected function traitMethod($model) {
        $model->doSomething();
    }
}

class Base {
    protected $_model;
}

class Child extends Base {
    use ExampleTrait;

    public function someMethod() {
        $this->traitMethod($this->_model);
    }
}

Both of these approaches let you utilize your IDE's type hinting.

Upvotes: 19

Related Questions