PHP Traits



Introduction

PHP doesn't support multiple inheritance. This limitation is overcome to some extent by the feature of traits. It is a mechanism of code reuse. Definition of trait is similar to class. However, it can't be instantiated directly. Instead, functionality of a trait is made available to a class by use keyword. Hence, a class can avail methods defined in a trait or can even override them. This is in addition to any other parent class that it might be inheriting.

A trait also is similar to an interface. The difference is that interface doesn't provide definition of method inside it, which must be done by implementing class. Trait method however, does provide definition, which may or may not be overridden by class that uses the trait.

Syntax

<?php
trait testtrait{
   public function test1(){
      //body of method
   }
}
//using trait
class testclass{
   use testtrait
   //rest of members in class
}
?>

Example

In following code, a trait with two methods is used in a class that overrides one of the methods

Example

 Live Demo

<?php
//definition of trait
trait testtrait{
   public function test1(){
      echo "test1 method in trait
";    }    public function test2(){       echo "test2 method in trait
";    } } //using trait class testclass{    use testtrait;    public function test1(){       echo "test1 method overridden
";    } } $obj=new testclass(); $obj->test1(); $obj->test2(); ?>

Output

The output is as below −

test1 method overridden
test2 method in trait

Trait in child class

This is the main advantage of trait. A class with a parent can also use a trait and may choose to override its method. Thus effectively achieveing multiple inheritance. Example of this feature is given below −

Example

 Live Demo

<?php
//definition of trait
trait testtrait{
   public function test1(){
      echo "test1 method in trait
";    } } //parent class class parentclass{    public function test2(){       echo "test2 method in parent
";    } } //using trait and parent class class childclass extends parentclass{    use testtrait;    public function test1(){       echo "parent method overridden
";    }    public function test2(){       echo "trait method overridden
";    } } $obj=new childclass(); $obj->test1(); $obj->test2(); ?>

Output

Above code produces following result −

parent method overridden
trait method overridden

Trait with interface

It is possible to have a class implementing an interface, extending other parent class and using trait at the same time

Example

 Live Demo

<?php
//definition of trait
trait mytrait{
   public function test1(){
      echo "test1 method in trait1
";    } } class myclass{    public function test2(){       echo "test2 method in parent class
";    } } interface myinterface{    public function test3(); } //using trait and parent class class testclass extends myclass implements myinterface{    use mytrait;    public function test3(){       echo "implementation of test3 method
";    } } $obj=new testclass(); $obj->test1(); $obj->test2(); $obj->test3(); ?>

Output

This will produce following output −

test1 method in trait1
test2 method in parent class
implementation of test3 method

conflict resolution

If a class uses two traits with a common method, their conflict is resolved by scope resolution operator and insteadof keyword

Example

 Live Demo

<?php
trait trait1{
   public function test1(){
      echo "test1 method in trait1
";    }    public function test2(){       echo "test2 method in trait1
";    } } trait trait2{    public function test1(){       echo "test1 method in trait2
";    }    public function test2(){       echo "test2 method in trait2
";    } } //using trait and parent class class testclass {    use trait1, trait2{       trait1::test1 insteadof trait2;       trait2::test2 insteadof trait1;    } } $obj=new testclass(); $obj->test1(); $obj->test2(); ?>

Output

Above script produces following result

test1 method in trait1
test2 method in trait2

Advertisements