PHP – Traits vs Interfaces

Once you get into writing more OOP PHP, you’ll find the term “trait” and “interface” thrown around a lot. What are they, and when should you be using each of them?

Previously, most developers would have created an abstract BaseClass from which most of their classes would extend, having a Base{Thing} in almost every directory. Abstracts, have their place, however they should not be the “default” that you go for. This is where Traits and Interfaces come in.


Firstly, we should understand what a Trait is.

…a mechanism for code reuse in single inheritance languages such as PHP. 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. The semantics of the combination of Traits and classes is defined in a way which reduces complexity, and avoids the typical problems associated with multiple inheritance and Mixins.
A Trait is similar to a class, but only 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.

In a nutshell, a Trait is a code snippet. It’s some form of functionality that can be shared multiple classes, potentially classes of different structure(s) and origin(s).

For instance, using the code in my Managing Filters In Laravel post, we can see that I’ve used a Trait to group the functionality together for all Models


namespace App\Traits;

use App\Filters\Filters;

trait HasFilters
    public function scopeFilter( $query, Filters $filters )
    	return $filters->apply( $query );

You can now add this Trait, to any Eloquent model, and you can filter it. Adding a Trait to a model is as easy as use App\Traits\HasFilters;

Interfaces / Contracts

These are slightly different. Instead of directly inheriting functionality, these will tie your classes into requiring some functionality to be declared and match a definition.

These are great at implementing the Factory Pattern in PHP, as you could have code to the following;

interface Factory
    public function create() : Object

Now any of your factories, can implement this Interface. Making your Dependency Injection far simpler, and happens to follow the Interface segregation principle quite nicely as well. You’ll also know that all of your Factories, have the public function create().