PHP traits: when to use one and what to use instead

PHP traits: when to use one and what to use instead

Are you asking yourself “when should I create a trait?”, and wondering what the advantages and drawbacks are? Or perhaps you simply do not know what a trait is in PHP, in which case I invite you to read the article I wrote on the subject.

For my part, the rare times I have created a trait were for building Elementor or Prestashop widgets. Take an Elementor widget: it already extends a class, and I am not keen on writing a class that extends another, which extends another, all the way down to my widget, just to share two or three methods. That is where the trait comes in and lets me share exactly those methods. In short, and to put it crudely, a trait amounts to a copy and paste.

php
trait CarouselTrait
{
    public function getScriptDepends()
    {
        return ['swiper'];
    }

protected function registerCarouselSection(array $args = [])
    {
       // Rest of the code that displays the configuration
       // options in Elementor
    }
}

The advantages of a trait in PHP

  • If you want to reuse code across several classes, a trait is an alternative to extending the class. In that case the trait may be the better option, because it is not part of the type hierarchy: a class that uses a trait is not “an instance of that trait”.

  • A trait can spare you a manual copy and paste by giving you a copy and paste at compile time.

The drawbacks of a trait in PHP

Traits also come with several problems of their own. For example:

  • When a trait adds one or more public methods to a class, you often want to declare those methods as an interface that the class would implement automatically by using the trait. That is impossible: a trait cannot implement an interface. You have to use the trait and implement the interface explicitly to get there.

  • Traits have no “private” methods and properties of their own. I often like to hide a few things from the class the trait is used in, but making anything “private” is impossible. Whatever is declared private in the trait remains reachable from the class that uses it. A trait therefore cannot encapsulate anything at all.

What are the alternatives to traits in PHP

In practice, there is always an alternative to using a trait. Here are a few of them:

  • If the trait carries the responsibilities of a service, it is better turned into a real service, which can and should be injected as a constructor argument into the service that needs it. This is what is called composing behaviour rather than inheriting behaviour. The same approach works when you want to get rid of parent classes.

  • If the trait adds behaviour to an entity and that behaviour is the same for another entity, it is often wiser to introduce a value object in PHP and use that instead.

Conclusion

To my mind traits are the easy way out: they are a way of organising your code rather than duplicating lines or nesting one inheritance inside another.

PHP

Damien Flandrin Web developer since 2010, creator of Gekkode and Email Impact. Every article is tested on a real project before publication. Contact
Newsletter

New tests, tutorials and projects, by e-mail.

Reproducible tests, versioned code, dated results. Never any spam.