← Back to the Blog

A simple guide to using Traits in Laravel 5

By Sid Young
A simple guide to using Traits in Laravel 5

Overview

If you have exposure to Object Oriented programming, then you will have been introduced to the concept of abstract classes and interfaces. A "Trait" is similar to an abstract class, in that it cannot be instantiated on its own but contains methods that can be used in a concrete class. Traits were introduced in PHP in version 5.4 and are used extensively in the Laravel Framework. They are ideal in reducing the limiting effect of single inheritance, thus enabling the exposing of methods as if they were defined in the calling class. The exact definition from the PHP site defines Traits as such:

“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.”

 

Example File

Creating a Trait is just like defining a class, the following simple example (excluding comments) shows a single file with one trait which has 2 methods:

<?php namespace App\Traits;

trait ExampleCode
{
    public function printThis()
    {
        echo "Trait executed";
        dd($this);
    }

    public function anotherMethod()
    {
        echo "Trait – anotherMethod() executed";
    }
}

Our example looks just like a class definition, except we use the keyword "trait", there is no constructor as it cannot be instantiated (just like an abstract class). It uses a name space of App\Traits to give it a clear grouping (you can use anything you like here). If you need to access code in other name spaces then just include the "use" statement (see example below) and create and call the method(s) as needed.

Within the file, function names must be unique and if they do conflict with existing methods then the following precedence takes effect:

  1. An inherited member from a base class is overridden by a member inserted by a Trait.
  2. Members from the current class override Trait methods.

Storing Traits

For convenience I created a directory under “app” called “Traits”, and placed my custom PHP files there. Each file uses the name of the Trait for logical correlation. By using a name space of “App\Traits” in each file the Framework was able to locate my files when I “use” them in another file.


Sample Usage Code:

<?php
/**
 * \class AdminLoginJob
 * @date 2016-11-03
 */
namespace App\Jobs;

use App\Jobs\Job;
use Illuminate\Contracts\Bus\SelfHandling;

use App\Traits\ExampleCode;

/**
 *  \brief Example code using a Trait in a Laravel "Job"
 */
class AdminLoginJob extends Job implements SelfHandling
{
    use ExampleCode;
    
    /**
     * Call trait to print something. Note the use of "$this".
     * 
     * @return void
     */
    public function __construct()
    {
        $this->printThis();
    }

   /**
     * Do more stuff here.
     * 
     * @return void
     */
     public function handle()
    {
        // never gets called in this example.
    }
}


Documenting Traits with Doxygen

I think code documentation is critical, so it pays to make an effort to insert formatted comments that can be collected by a suitable tool and generated onto a web site for easy access. I tend to CRON my document generation, so as code is edited and saved new comments and code appear in the reports. Another handy feature is leaving TODO notes so code can be revisited to introduce new functionality. To achieve this I use Doxygen as my main tool but also run phpDocumentor2 and phpDox over the code, this given me lots of useful info in different formats.

By default Doxygen does not support PHP Traits in its documentation output, however several StackExchange posts cover a workaround:

Related posts:

Manual Page on input Filters:

 

Enjoy!

 

-oOo-