[printfriendly]
Introduction
Trait is the new concept introduced in PHP 5.4. Which remove the limitation of the multiple inheritance in PHP. Before PHP 5.4, PHP support single inheritance and multiple interface but trait is going to remove the limitation of not having multiple inheritances. In This Tutorial, I’ll show a brief walkthrough of traits and I’ll show you how they can be used in real life situations.
What is trait?
According to php.net,
“Traits are 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.”
Why Use trait?
The main concept behind the trait is the reusability of the code. trait 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 trait is to gain the benefits of multiple inheritance and alternatively of the code reusability.
How to Use trait?
Trait can be initialized with the keyword trait.
Let’s see how to start with the trait:
<?php trait Foo { public function first_method() { echo "Hello"; /* Code Here */ } public function second_method() { echo "World"; /* Code Here */ } } ?>
Trait can be used within class using use keyword.
<?php class Bar { // Using the Trait Here use Foo; } $obj = new Bar; // Executing the method from trait $obj->first_method(); //Hello $obj->second_method(); // World ?>
Traits can’t be instantiated so you can never do something like
<?php $obj = new Foo; ?>
Without getting a big fatal error, but you can call it’s function statically.
<?php Foo::first_method(); ?>
It might show you a warning ‘Strict Standards: Non-static method Foo::first_method(); should not be called statically’, but you can make it a static function, and it will work without warnings.
Moving on, further exploring the powers of Traits
Precedence in traits
If same function found on multiple level(for example in child class, base class and trait) then there is some specific precedence order defined in php for choosing the function. For example
<?php class Base{ public public function sayHello(){ echo "say hello from base"; } } trait trt{ public function sayHello() { echo "say hellow from trait"; } } class Child extends Base{ use trt; public function sayHello(){ echo "hello from child class"; } } $objCls = new Child; $objCls->sayHello(); ?>
Output:
hello from child class
Now in above code output will be “hello from child class”.Because precedence in the execution is like below list
- If method will be available in the main class(main_child in my example) then it will ignore everything and will use main class.
- If method is not available in main class and available in parent class and trait then it will choose from trait.
Using multiple traits
A class can use multiple traits. The following example demonstrates how to use multiple traits in the IDE class.
<?php trait Subscriber{ public function subscriberLogin() { echo "You\'re Logged in as Subscriber". '<br/>'; } } trait Contributor{ public function contributorLogin() { echo "You're Logged in as Contributor". '<br/>'; } } trait Author{ public function AuthorLogin() { echo "You're Logged in as Author." . '<br/>'; } } trait Administrator{ public function AdministratorLogin(){ echo "You're Logged in as Administrator" . '<br/>'; } } class Member{ use Subscriber, Contributor, Author, Administrator; public function run() { $this->subscriberLogin(); $this->contributorLogin(); $this->AuthorLogin(); $this->AdministratorLogin(); echo 'Members Login...done' . '<br/>'; } } $authentication = new Member(); $authentication->run(); ?>
Output:
You’re Logged in as Subscriber
You’re Logged in as Contributor
You’re Logged in as Author.
You’re Logged in as Administrator
Members Login…done
Conflict Resolution in PHP 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 trait then it will give you Fatal Error.
But actually we can instruct the compiler for which method to use. This can be done using insteadofoperator.
Let’s have an example for this:
<?php trait Foo { public function first_function() { echo "From Foo Trait"; } } trait Bar { public function first_function() { echo "From Bar Trait"; } } class FooBar { use Foo, Bar { // This class will now call the method // first function from Foo only Foo::first_function insteadof Bar; } } $obj = new FooBar; $obj->first_function(); ?>
Output
From Foo Trait
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 as operator to the rescue. This operator is used for aliasing. Let’s see how it works:
<?php trait Foo { public function first_function() { echo "From Foo Trait"; } } trait Bar { public function first_function() { echo "From Bar Trait"; } } class FooBar { use Foo, Bar { // This class will now call the method // first function from Foo Trait only Foo::first_function insteadof Bar; // first_function of Bar can be // accessed with second_function Bar::first_function as second_function; } } $obj = new FooBar; // Output: From Foo Trait $obj->first_function(); // Output: From Bar Trait $obj->second_function(); ?>
Changing Method Visibility
As you have seen in my first example that I have used access modifier(public) in one of the function of traits. So whenever that trait will be used in any class the method will be public. You can create trait’s method with modifier public, private, protected. Following is example of the access modifier.
<?php trait visible{ public function pub(){ echo "this is public method"; } private function priv(){ echo "this is private"; } protected function proc(){ echo "echo this is protected function"; } } class cls{ use visible; function callPriv(){ $this->priv(); } } $objCls = new cls(); $objCls->pub();//echo this is public method //$objCls->priv();//Fatal error $objCls->callPriv(); //this is private ?>
Now you can change access modifier of trait Methods using as keyword with following syntax.
<?php trait visible{ public function pub(){ echo "this is public method"; } private function priv(){ echo "this is private"; } protected function proc(){ echo "echo this is protected function"; } } class cls{ use visible{ priv as public; } function callPriv(){ $this->priv(); } } $objCls = new cls(); $objCls->pub();//echo this is public method //$objCls->priv();//This is private $objCls->callPriv(); //this is private ?>
You can also modified the name of method of trait using as keyword.
<?php trait visible{ public function pub(){ echo "this is public method"; } private function priv(){ echo "this is private"; } protected function proc(){ echo "echo this is protected function"; } } class cls{ use visible{ priv as public publ; } function callPriv(){ $this->publ(); } } $objCls = new cls(); $objCls->pub();//echo this is public method //$objCls->publ();//This is private $objCls->callPriv(); //this is private ?>
Traits Composed from Traits
A trait can be composed of other traits by using the use
statement in the trait’s declaration. See the following example:
<?php trait Hello { function sayHello() { echo "Hello"; } } trait World { function sayWorld() { echo "World"; } } trait HelloWorld { use Hello, World; } class MyWorld { use HelloWorld; } $world = new MyWorld(); echo $world->sayHello() . " " . $world->sayWorld(); //Hello World ?>
Traits and Properties
<?php trait Calories { public $banana = 105; public $cake = 300; public $donation = 205; } class Cookbook { use Calories; } $c = new Cookbook; printf($c->banana);</pre> ?>
Beware, you will not be able to define the same property in the Cookbook class. Meaning that if you do something like:
<?php class Cookbook { use Calories; public $banana = 105; // if same value, this will result into a warning (E_STRICT) public $banana = 106; // if different value, this will result into a fatal error } ?>
So keep in mind, once you define properties in a trait you are not able to redefine them in the class.
Traits and Static methods and Properties
Traits can define both static members and static methods.
<?php trait Calories { public $banana = 105; public $cake = 300; public $donation = 205; } class Cookbook { use Calories; } $c = new Cookbook; printf($c->banana);</pre> ?>
Beware, you will not be able to define the same property in the Cookbook class. Meaning that if you do something like:
<?php class Cookbook { use Calories; public $banana = 105; // if same value, this will result into a warning (E_STRICT) public $banana = 106; // if different value, this will result into a fatal error } ?>
Output:
Donate
Donate
2
Traits and Abstract members
Here’s how you can make a trait force you to implement a function.
<?php trait Helper { abstract public function greet(); } class Foo { use Helper; public function greet($name){ printf('Hi there %s !', $name); } } $foo = new Foo; $foo->greet('Awesome Man'); ?>
Output:
Hi there Awesome Man !
Practical example
Sorting a Array Using Trait
<?php trait SortStrategy { private $sort_field = null; private function string_asc($item1, $item2) { return strnatcmp($item1[$this->sort_field], $item2[$this->sort_field]); } private function string_desc($item1, $item2) { return strnatcmp($item2[$this->sort_field], $item1[$this->sort_field]); } private function num_asc($item1, $item2) { if ($item1[$this->sort_field] == $item2[$this->sort_field]) return 0; return ($item1[$this->sort_field] < $item2[$this->sort_field] ? -1 : 1 ); } private function num_desc($item1, $item2) { if ($item1[$this->sort_field] == $item2[$this->sort_field]) return 0; return ($item1[$this->sort_field] > $item2[$this->sort_field] ? -1 : 1 ); } private function date_asc($item1, $item2) { $date1 = intval(str_replace('-', '', $item1[$this->sort_field])); $date2 = intval(str_replace('-', '', $item2[$this->sort_field])); if ($date1 == $date2) return 0; return ($date1 < $date2 ? -1 : 1 ); } private function date_desc($item1, $item2) { $date1 = intval(str_replace('-', '', $item1[$this->sort_field])); $date2 = intval(str_replace('-', '', $item2[$this->sort_field])); if ($date1 == $date2) return 0; return ($date1 > $date2 ? -1 : 1 ); } } class Product { public $data = array(); use SortStrategy; public function get() { // do something to get the data, for this ex. I just included an array $this->data = array( 101222 => array('label' => 'Awesome product', 'price' => 10.50, 'date_added' => '2012-02-01'), 101232 => array('label' => 'Not so awesome product', 'price' => 5.20, 'date_added' => '2012-03-20'), 101241 => array('label' => 'Pretty neat product', 'price' => 9.65, 'date_added' => '2012-04-15'), 101256 => array('label' => 'Freakishly cool product', 'price' => 12.55, 'date_added' => '2012-01-11'), 101219 => array('label' => 'Meh product', 'price' => 3.69, 'date_added' => '2012-06-11'), ); } public function sort_by($by = 'price', $type = 'asc') { if (!preg_match('/^(asc|desc)$/', $type)) $type = 'asc'; switch ($by) { case 'name': $this->sort_field = 'label'; uasort($this->data, array('Product', 'string_'.$type)); break; case 'date': $this->sort_field = 'date_added'; uasort($this->data, array('Product', 'date_'.$type)); break; default: $this->sort_field = 'price'; uasort($this->data, array('Product', 'num_'.$type)); } } } $product = new Product(); $product->get(); $product->sort_by('date'); ?> <table border="1" width="100%"> <tr> <th>SL</th> <th>Label</th> <th>Price</th> <th>Date Added</th> </tr> <?php $i=1; foreach($product->data as $value){ extract($value); ?> <tr> <td><?php echo $i++; ?></td> <td><?php echo $label; ?></td> <td><?php echo $price; ?></td> <td><?php echo $date_added; ?></td> </tr> <?php } ?> </table>
Output:
goodgood verygood 😀
Multiple Inheritance in PHP using Traits

Hi, My name is Masud Alam, love to work with Open Source Technologies, living in Dhaka, Bangladesh. I’m a Certified Engineer on ZEND PHP 5.3, I served my first Fifteen years a number of leadership positions at AmarBebsha Ltd as a CTO, Winux Soft Ltd, SSL Wireless Ltd, Canadian International Development Agency (CIDA), World Vision, Care Bangladesh, Helen Keller, US AID and MAX Group where I worked on ERP software and web development., but now I’m a founder and CEO of TechBeeo Software Company Ltd. I’m also a Course Instructor of ZCPE PHP 7 Certification and professional web development course at w3programmers Training Institute – a leading Training Institute in the country.
Nice class and awesome topic………………………..
in two words……awesome,excellent
Nice class
That’s awesome article about PHP Traits and Thank you very much Sir.
I got one error : Fatal error: Multiple access type modifiers are not allowed in ……
# it’s may be type mistake.
class Base{
public public function sayHello(){
//remove please one public keyword
echo “say hello from base”;
}
}