Traits in PHP
In previous chapters of inheritance, abstract class, an inheritance we have seen the importance and benefits of code reusability. In this tutorial you will what are Traits in PHP in detail.
Using inheritance you can achieve a parent-child relationship where you can keep the reusable code in the parent class and then inherit it in child classes.
But in inheritance there is one problem, rather you can say it as a limitation of an inheritance. In inheritance, you can inherit only one parent class in a child class.
Multiple class inheritance is not allowed in inheritance. Only single inheritance is present in inheritance.
Though you can use interface for multiple inheritances, another limitation arises that method definition is not allowed in an interface.
You have to implement the method definition only in the child class. So the code reusability will not be very simple and straightforward in this case.
So to overcome this limitation of multiple inheritance new feature called “Traits” is introduced in PHP 5.4 version.
Let’s see more about traits.
What are the Traits in PHP?
The main objective of Traits in PHP is code reusability. Before PHP 5.4 which is possible only by using inheritance using parent-child relationship.
But the limitation of not having multiple inheritances causes the complexity of code.
The trait is a special kind of feature which is introduced in PHP 5.4 to overcome this limitation of multiple inheritances in PHP OOP. You can achieve multiple inheritances like functionality using traits.
How do traits look?
Traits in PHP are the same as classes. The trait can have properties and methods with access specifiers. Methods can also have their definition implemented inside traits.
But just like an abstract class whose object cannot be created, an object of a trait is also cannot be created.
Let’s see the syntax of traits:
trait Man { public function walk() { echo "Man is walking."; } }
Traits in PHP can be defined using a keyword “trait”.
As you see in the above example I have defined a trait called Man. This Man trait is having a method definition walk() in it.
How to use Traits in PHP?
You can use traits using a keyword “use” inside a class. Just type keyword “use” following the trait name inside a class.
<?php trait Man { public function walk() { echo "Man is walking."; } } class TestWalk { //Using trait Man inside a class use Man; } $tw = new TestWalk; $tw->walk(); ?>
The output will be:
Man is walking.
In the above example, I have used the trait “Man” inside a class “TestWalk” using a keyword “use” following a trait name “Man”. Like “use Man;”.
When you use a trait inside a class, methods defined inside a trait gets inherited inside that class.
That’s why we are able to use the “walk” method of a trait using an object of “TestWalk” class.
One thing to remember again, that you are not able to create an object of Traits in PHP.
Using multiple Traits in PHP
As I have told you earlier that traits are created to overcome the limitation of an inheritance where you cannot create multiple inheritances to the classes.
You can use multiple traits inside a class using the same “use” keyword and names of traits with comma-separated.
Let’s see an example.
<?php trait Man { public function walk() { echo "Man is walking."; } } trait Dog { public function dogWalk() { echo "<br>Dog is walking."; } } class TestWalk { //Using traits Man and Dog inside a class use Man,Dog; } $tw = new TestWalk; $tw->walk(); $tw->dogWalk(); ?>
The output will be:
Man is walking. Dog is walking.
In this way, you can use more than one trait inside any class for code reusability.
Using traits inside other traits
You can also add one trait inside another using the same “use” keyword. This will, even more, simplify the traits functionality.
Example:
<?php trait Man { public function walk() { echo "Man is walking."; } } trait Dog { use Man; public function dogWalk() { echo "<br>Dog is walking."; } } class TestWalk { //Using trait Dog inside a class use Dog; } $tw = new TestWalk; $tw->walk(); $tw->dogWalk(); ?>
The output:
Man is walking. Dog is walking.
As you see in the above example I have used a trait Man inside a Dog trait, and then only Dog trait is added inside a TestWalk class.
Even now also you can use both the traits Man and Dog using TestWalk object.
Trait’s method conflict resolution
When you are using multiple Traits in PHP sometimes its possible few traits are having common method name. In this case, PHP will through a fatal error showing that there is a method name conflict in traits.
We can resolve this conflict issue by using the keyword “insteadof“.
Let’s see an example:
<?php trait Man { public function walk() { echo "Man is walking."; } } trait Dog { public function walk() { echo "<br>Dog is walking."; } } class TestWalk { //Using traits Man and Dog inside a class use Man,Dog{ //Same method name conflict resolved using insteadiof keyword. Man::walk insteadof Dog; } } $tw = new TestWalk; $tw->walk(); ?>
In the above example, I have made the name of methods in both traits same, i.e “walk()”.
If you run by just making same method names you will get a fatal error.
To resolve this issue in class TestWalk I have used “insteadof” keyword with the names of the traits in particular fashion. The code looks like this:
use Man,Dog{ Man::walk insteadof Dog; }
There is a just simple modification in writing names of traits. Here in curly braces, I have written a statement “Man::walk insteadof Dog;”.
This statement is saying “use the walk method of a Man trait instead of a Dog trait.
Here you can use a scope resolution operator after the name of a trait whose method you want to use and following that the conflicted method name, then use “insteadof” keyword and later the name of another trait where the same method name is present.
Traits method name aliasing
In the above method name conflict example, we have seen that if there are two methods with the same name then you can use a method on any one trait.
But if you also want to use the method of another trait which may have different functionality though have the same method name?
In this case, you use the method name aliasing feature of traits.
Aliasing means giving a new name. You can give a new name to that same method using a keyword “as” which you want to use in a class.
Let’s see an example:
<?php trait Man { public function walk() { echo "Man is walking."; } } trait Dog { public function walk() { echo "<br>Dog is walking."; } } class TestWalk { //Using traits Man and Dog inside a class use Man,Dog{ //Same method name conflict resolved using insteadiof keyword. Man::walk insteadof Dog; //Aliasing walk method with dogWalk Dog::walk as dogWalk; } } $tw = new TestWalk; $tw->walk(); $tw->dogWalk(); ?>
In the above example, I have used the statement “Dog::walk as dogWalk;”.
This statement is saying “use a method walk of a Dog with a new name dogWalk”.
Here you need to use a trait name whose method you want to alias and use, following a scope resolution operator, then a method name, then “as” keyword and finally a new name.
Now as you see we have called dogWalk method with an object which is showing the execution of a walk method of a Dog trait.
In this way, you can use both the methods which are having the same name in more than one traits.
Using abstract methods inside traits
You can also declare abstract methods inside Traits in PHP.
Later the class who is using a trait needs to implement that abstract method inside it, just like abstract class inheritance.
Example:
<?php trait Man { //Abstract method declaration inside a trait. public abstract function dance(); public function walk() { echo "Man is walking."; } } class TestWalk { //Using traits Man and Dog inside a class use Man; public function dance() { echo "<br>Now this man is dancing."; } } $tw = new TestWalk; $tw->walk(); $tw->dance(); ?>
As you see in the above example I have declared an abstract method “dance()” in a trait Man.
This dance() is them implemented inside a class TestWalk and used using an object of this class.
Using properties inside traits
You can also declare properties inside traits. Those properties then can be used inside a class where the traits are used.
Example:
<?php trait Man { protected $name = "Jhon"; //Abstract method declaration inside a trait. public abstract function dance(); public function walk() { echo $this->name." is walking.<br>"; } } class TestWalk { //Using traits Man and Dog inside a class use Man; public function dance() { echo $this->name." man is dancing."; } } $tw = new TestWalk; $tw->walk(); $tw->dance(); ?>
In the above example, I have declared a protected property “$name” inside a Man trait and assigned the name “Jhon” to it.
The $name property is used in both the Man trait and a class TestWalk which is using a Man trait.
In this way, you can use the trait functionalities whenever you want to code reuse and want multiple inheritance functionality.
Hope this tutorial clears your view about the Traits in PHP. Please comment if you are stuck at any point. I will try to help you as early as possible.
I will see you in our next topic which is type hinting in PHP.