PHP traits provide a convenient means of sharing methods between classes. There are times though that we may need to override or extend a method defined in a trait attached to a class. Let’s take a look at how we can achieve this.
Let’s start by defining a very simple trait as an example called FooTrait
that contains the definition for a public method called bar()
:-
trait FooTrait
{
public function bar()
{
return 'A';
}
}
We can then assign that trait to a class and call bar()
as a method of the class:-
class Example
{
use FooTrait;
}
echo (new Example())->bar(); // Outputs 'A'
The methods of the attached trait essentially work as though they’ve been copied and pasted into our Example
class.
If we were to then define a new bar()
method in our Example
class that will override the trait’s bar()
method then this new method would be run instead:-
class Example
{
use FooTrait;
public function bar()
{
return 'B';
}
}
echo (new Example())->bar(); // Outputs 'B'
This covers overriding a trait’s method, but what if we want to extend the method rather than replace it? Unlike class inheritance we can’t just extend the bar()
class by calling the parent
method. By defining bar()
in our class it has replaced the bar()
method defined in the attached FooTrait
. Therefore, if we want to extend the method defined in our trait from our class we need to rename the trait’s bar()
method to something like traitBar
in our class and then directly call traitBar()
inside our class’ bar()
method like this:-
class Example
{
use FooTrait {
bar as traitBar;
}
public function bar()
{
return $this->traitBar() . 'B';
}
}
echo (new Example())->bar(); // Outputs 'AB'
This way we can extend the method in a similar fashion to extending an inherited class method. Renaming a trait method like this can also be useful when attaching multiple traits to a class where there might be a conflict in method names.
So there you have it, we’ve seen how we can both override and extend a trait method. Traits are a useful way of keeping our code DRY (i.e. not repeating ourselves) and sharing methods amongst classes. The fact that we can override and extend the methods from a trait makes them extremely useful!