What is traits?
Traits is the new concept introduced in PHP 5.4. Which likes to remove the limitation of the multiple inheritance in single inheritance language PHP.
Before PHP 5.4, PHP support single inheritance and multiple interface but traits is going to remove the limitation of not having multiple inheritance.
Why Use traits?
The main concept behind the traits is the reusability of the code. traits seems to be very useful in terms of code reusability for the in language which supports only single inheritance like PHP.
So main reason to use the traits is to gain the benefits of multiple inheritance and alternatively of the code reusability.
How to Use traits?
Traits can be initialized with the keyword [code]trait[/code].
Let’s see how to start with the trait:
[cc lang=”php”]
trait first_trait
{
function first_method() { /* Code Here */ }
function second_method() { /* Code Here */ }
}
[/cc]
Traits can be used within class using [code]use[/code] keyword.
[cc lang=”php”]
class first_class
{
// Using the Trait Here
use first_trait;
}
$obj = new first_class();
// Executing the method from trait
$obj->first_method(); // valid
$obj->second_method(); // valid
[/cc]
Make note that we can not create an object of the class using [code]new[/code] keyword just like class.
Using Multiple traits
We can use multiple traits in a class. So here is what we can consider as a multiple inheritance.
So any class which uses the multiple traits will have all methods available in both traits.
Let’s see how it works:
[cc lang=”php”]
trait first_trait
{
function first_method() { echo “method1”; }
}
trait second_trait
{
function second_method() { echo “method2”; }
}
class first_class
{
// now using more than one trait
use first_trait, second_trait;
}
$obj= new first_class();
// Valid
$obj->first_method(); // Print : method1
// Valid
$obj->second_method(); // Print : method2
[/cc]
Traits Contains the Trait
Here one more interesting thing is the we can use the traits inside another traits. We can say this as an extending the traits.
[cc lang=”php”]
trait first_trait
{
function first_method() { echo “method1”; }
}
trait second_trait
{
use first_trait;
function second_method() { echo “method2”; }
}
class first_class
{
// now using
use second_trait;
}
$obj= new first_class();
// Valid
$obj->first_method(); // Print : method1
// Valid
$obj->second_method(); // Print : method2
[/cc]
Note: traits can not be initialized with the keyword [code]new[/code] same as class.
Abstract Methods in Traits
We can declare abstract method in traits. So after declaring the abstract method in traits, as class must have to implement that method which uses that traits. This is the same concept as the abstract class and abstract method.
[cc lang=”php”]
trait first_trait
{
function first_method() { echo “method1”; }
// any class which use this trait must
// have to implement below method.
abstract public function second_method();
}
class first_method
{
use first_trait;
function second_method()
{
/* Code Here */
}
}
[/cc]
Note: trait can be composed from trait.
Conflicts in Traits
There can be a case, if any class using the more than one trait and two trait have same methods defined. In that case if you use two traits then it will give you Fatal Error.
But actually we can instruct the compiler for which method to use. This can be done using [code]insteadof[/code] operator.
Let’s have an example for this:
[cc lang=”php”]
trait first_trait
{
function first_function()
{
echo “From First Trait”;
}
}
trait second_trait
{
function first_function()
{
echo “From Second Trait”;
}
}
class first_class
{
use first_trait, second_trait
{
// This class will now call the method
// first function from first_trait only
first_trait::first_function insteadof second_trait;
}
}
$obj = new first_class();
// Output: From First Trait
$obj->first_function();
[/cc]
So now we have removed the confliction if the same function names. But what if you still want to use the methods of the both traits?
So in that case you can have [code]as[/code] operator to the rescue. This operatoe is used for aliasing. Let’s see how it works:
[cc lang=”php”]
trait first_trait
{
function first_function()
{
echo “From First Trait”;
}
}
trait second_trait
{
function first_function()
{
echo “From Second Trait”;
}
}
class first_class
{
use first_trait, second_trait
{
// This class will now call the method
// first function from first_trait only
first_trait::first_function insteadof second_trait;
// first_function of second_traits can be
// accessed with second_function
second_trait::first_function as second_function;
}
}
$obj = new first_class();
// Output: From First Trait
$obj->first_function();
// Output: From Second Trait
$obj->second_function();
[/cc]
Points to Keep in Mind About trait
- traits integrate into the precedence order of method overriding.
- traits can not be initialized with the keyword new same as class.
- traits can be composed from traits.
- We can use multiple traits in one class.
- traits supports all modifiers like final, static and abstract.
- We can use [code]insteadof[/code] and [code]as[/code] operators to resolve the conflicts in traits.
Coclusion
The main the major benefit of using the traits is code reusability and multiple inheritamce like functionality.
It would be great if you share your thought on traits about how you are plannig to use this upcoming feature and what are the other benefits of using the traits.
Note: PHP 5.4 is not stable yet, So you can visit this link to run the PHP code using 5.4 version.
How is managed the method overriding when a class uses 2 traits which implements the same function ?
[cc lang=”php”]
trait first_trait
{
function first_method() { echo “method1 A”; }
}
trait second_trait
{
function first_method() { echo “method1 B”; }
}
class first_class
{
use first_trait, second_trait;
}
$obj= new first_class();
$obj->first_method(); // Print : ???
[/cc]
It’s one of the complexity of multiple inheritance.
Hi YoTsumi,
It will give Fatal Error: Trait method first_method has not been applied, because there are collisions with other trait methods on first_class
Please refer below link for code demo,
http://codepad.viper-7.com/Gr65lj
Hi YoTsumi ,
I have edited the post which describes your confusion about the multiple inheritance. So is that what you are looking for?
Thank you for that answer, it’s exactly what i was looking for.
Glad to Help :)
When the traits have the same property it’s done with a fatal error too.
And you can’t apply and alias or insteadof at propertyes like you can do to methods… i think we got a bug ;)
@kinn:
Yes seems to be like that… ;)
I fail to see the point of the insteadof operator. The only information the interpreter really needs from us is which trait’s method to use, and that could be unambiguously specified by just naming that trait, without having to name all the other traits after the insteadof keyword.
[…] of the class the trait is used in.__TRAIT__This is introduced in PHP 5.4 and it will return the traits name in which this is used.__METHOD__This will return name of the class method name and it will […]
This is really a good post to understand what actually TRAIT is :)
[…] of the newly added feature in PHP. For some points I have already posted the article for example, Traits in PHP 5.4, Session Status in PHP 5.4. For the remaining one I will post the articles later […]
[…] ????wiki.php???????? (click) ??????????(click) […]
Nice Article Avinash
Keep posting :)
When reading about traits one really would like to flee to Java.
[…] http://localhost/xpertdev/2011/11/trait-in-php/ […]
Points to be kept in mind
—-
trait integrate into the precedence order of method overriding.
By this do you mean to say that if the class using the trait already has a function contained in the trait, the class function will override the trait function?
The tutorial/post was really helpful
[…] | 2012 ? 09 ? 23 ? | Leave your comment ??????? http://localhost/xpertdev/2011/11/trait-in-php/ ?????????? […]
[…] http://localhost/xpertdev/2011/11/trait-in-php/ […]