PHP - Traits vs Interfaces
Oliver Sarfas • January 10, 2019
programmingOnce 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.
Traits
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.
http://php.net/manual/en/language.oop5.traits.php
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
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().