5 minutes to read, 1.64K views since 2017.02.17

Traits in php

What are the traits?

Trait is a mechanism to ensure the reuse of code in languages ​​that supports single inheritance, such as PHP. Traits used to reduce some of the common inheritance restrictions, allowing the developer to reuse sets of methods freely in several independent classes and implemented using different architectures build classes. The semantics of the combination of Traits and classes is defined in such a way as to reduce the level of complexity and avoid common problems associated with multiple inheritance in other languages (c++). This is an addition to the normal inheritance which allows you to make a horizontal composition of behavior.

As for me - traits are the parts of classes that you can inject into standart classes. You can make some functional class using number of traits.

<?php

trait JsonOutputer {

    public function outputJson($data){
        return json_encode($data);
    }

} 

Here's the example of trait which consists one method. You can use It like follows:

class SomeClass {
    use JsonOutputer;
}

Now, theSomeClass gets an outputJson method from trait. You can use as much as you want traits in one class. Traits are the mix-ins, you can't create instance of trait, only the instance of class that uses trait. You can use your traits only at compile-time: you can't use or not use traits on some conditions, so the next is wrong, you can't do like that:


If ($something){
    use SuperTrait:
}

where and how traits in php are used

Situations when traits can help, and only traits can be used is the next: imagine you have some class, controller from some mvc-framework:

<?php

class ProductsApiController extends ApiController {
    // actions code

    public function doSomething(){
        // a lot of code
    }
}

class CustomersApiController extends ApiController {
    // actions code

    public function doSomething(){
        // same as in ProductsApiController
    }
}

So, you have two different classes and one copy-pasted method doSomething which is identical in both classes. You can't put it to the parent ApiController because its used only in this two classes. To avoid copy-pasting the code there is two ways except traits:

  • if doSomthing doesn't have dependencies on ApiController we can make library class DoSomethingLibrary and use its methods somewhere in the controllers
class DoSomethingLibrary {

    public function doSomething(){
        // a lot of code
    }

}

we even can make this method statically and call it without creating any objects. But this only possible if there is no any dependencies.

  • in case we have dependencies wecould make one common parent controller for two controllers and this way seems to me most laconic:
class DoSomethingController extends  ApiController {

    public function doSomething(){
        // a lot of code
    }

}

Also, we need to change parent class in two classes to DoSomethingController.

  • The third way is using traits. Declare a trait at first with our function/method:
<?php

trait SomeFunctionality {
    public function doSomething(){
        // a lot of code
    }
}

And then, declare usage of a trait in our classes declaration:

<?php

class ProductsApiController extends ApiController {
    use SomeFunctionality; // here's the declaration of trait usage

    // actions code
}

class CustomersApiController extends ApiController {
    use SomeFunctionality; // here's the declaration of trait usage 

    // actions code
}

We don't need to care about dependencies here, because using a trait means injecting of its content into a class content: class gets all methods, also private and protected, all constants and fields.

Traits were invented in php 5.4, before this version of php you can't use them. Traits are very flexible way to write code: Traits support inheritance from traits, you can also use traits in trait declaration. Recursion! ;).Nevertheless traits has some drawbacks: contstructor method is not working with traits.

Traits in php is a language feature that allows you to reach semi multiinheritance of classes - each class can use number of traits and the class itself gets all properties and methods of a trait

Read next article Catching and throwing exceptions, error handling in course Basic PHP