PHP Traits Explained
Eelco Verbrugge
Posted on January 13, 2022
In line of my previous blogs PHP Interfaces Explained and PHP Abstract Classes Explained, I'll explain PHP Traits today.
In PHP a child class can inherit only from one single parent. This allows a class to reuse methods from vertically hierarchy by extending an Abstract class.
If you like to reuse methods in many different classes in horizontally hierarchy, we use Traits. Traits are used to group methods and implement in multiple classes. Traits can't be initiated on it's own like a normal class could.
For example
Let's say we would like to check if a user has access in many classes:
trait Access
{
public function hasAccess(string $username): bool
{
//..Check if $username has access
}
}
Everyone who can access Files, is allowed to download them. To use this Trait into our class:
class File
{
use Access;
public function download(string $username): Response
{
if ($this->hasAccess($username)) {
//..Download file x
}
}
}
Wherever you implement your Trait with use Access; you are able to refer to $this->yourMethod()
as of it would be one of this class. Which in this case is only hasAccess()
.
Multiple inheritance
What if you need multiple inheritance to reuse various methods in many different classes in horizontally hierarchy?
This is easily done, let's create an other one:
trait Ability
{
public function canUpload(string $username): bool
{
//..Check if $username can upload
}
}
We want to check if our $username can access files and is allowed to upload as well:
class File
{
use Access, Ability;
public function upload(string $username): Response
{
if ($this->hasAccess($username) && $this->canUpload($username)) {
//..Upload file
}
}
}
Tadaa! As you can see, Trait's are easily implemented and freely used everywhere you want in your project.
Bad practice
If ever used duplicated methods by implementing multiple Traits, an error will arise. Let's say both Traits have the method canDownload()
implemented, PHP wouldn't know which one to use. This is solved by the keyword insteadof
:
class File
{
use Access, Ability{
Access::canDownload insteadof Ability;
}
public function upload(string $username): Response
{
if ($this->hasAccess($username) && $this->canUpload($username)) {
//..Upload file
}
}
}
Let me know your experience with Traits and best practices.
Posted on January 13, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.