Home » Code » What are PHP Traits?

What are PHP Traits?

Posted by on June 25th, 2014

What are PHP Traits
One of the problems of PHP as a programming language is the fact that you can only have single inheritance. This means a class can only inherit from one other class.

However, a lot of the time it would be beneficial to inherit from multiple classes. For example, it might be desirable to inherit methods from a couple of different classes in order to prevent code duplication.

This problem can lead to class that has a long family history of inheritance which often does not make sense.

In PHP 5.4 a new feature of the language was added known as Traits. A Trait is kind of like a Mixin in that it allows you to mix Trait classes into an existing class. This means you can reduce code duplication and get the benefits whilst avoiding the problems of multiple inheritance.

In this article I’m going to be exploring Traits to show how you can use them in your projects.

What are PHP Traits?

A Trait is simply a group of methods that you want include within another class. A Trait, like an abstract class, cannot be instantiated on it’s own.

An example of a Trait could be:

trait Sharable {

  public function share($item)
    return 'share this item';


You could then include this Trait within other classes like this:

class Post {

  use Sharable;


class Comment {

  use Sharable;


Now if you were to create new objects out of these classes you would find that they both have the share() method available:

$post = new Post;
echo $post->share(''); // 'share this item' 

$comment = new Comment;
echo $comment->share(''); // 'share this item'

How do Traits work?

As you can see from the example above, both the Post and the Comment objects have the share() method available despite not having that method defined.

A Trait is basically just a way to “copy and paste” code during run time.

This means the Trait is copied in to the Post and Comment classes so when you instantiate a new instance, the share() method code will be available.

How are Traits different to Abstract classes?

A Trait is different to an Abstract class (What are Abstract classes?) because they do not rely on inheritance.

Imagine if the Post and the Comment class had to inherit from a AbstractSocial class. We are most likely going to want to do more than just share posts and comments on social media websites, so we’ll probably end up with a complicated inheritance tree like this:

class AbstractValidate extends AbstractCache {}
class AbstractSocial extends AbstractValidate {}
class Post extends AbstractSocial {}

This complicated inheritance is pretty nasty, but it also adds complication when a simpler object does not have a similar inherence structure. For example, if we had a Message object that shouldn’t allow social sharing, then this object would require a slightly different inheritance structure.

How are Traits different to Interfaces?

Traits kind of look a lot like Interfaces. Both Traits and interfaces are usually simple, concise and not much use without an actual implemented class. However the difference between the two is important.

An interface is a contract that says “this object is able to do this thing”, whereas a Trait is giving the object the ability to do the thing.

For example:

// Interface
interface Sociable {

  public function like();
  public function share();


// Trait
trait Sharable {

  public function share($item)
    // share this item


// Class
class Post implements Sociable {

  use Sharable;

  public function like()


In this example we have a Sociable interface that states that the Post object is able to like() and share().

The Sharable Trait implements the share() method and the like() method is implemented in the Post class.

So as you can see we could type hint the Post object to see if it is sociable (it implements the Sociable interface), whilst the Trait defines a reusable method that we can then mix in to other similar classes:

$post = new Post;

if($post instanceOf Sociable)
  $post->share('hello world');

What are the benefits of Traits?

The benefit of using Traits is that you reduce code duplication whilst preventing complicated class inheritance that might not make sense within the context of your application.

This allows you to define simple Traits that are clear and concise and then mix in that functionality where appropriate.

What are the drawbacks of Traits?

However with that being said, there are possible drawbacks when using Traits too.

Traits make it very easy to write bloated classes that have too much responsibility. A Trait is essentially a way to “copy and paste” code between classes. By having a way to very simply add another group of methods to a class, it’s very easy to diverge from the single responsibility principle.

Other drawbacks to using Traits are not being able to see all the methods of a class when looking at the source code as well as method conflicts or duplication of logic.

I think Traits, when used correctly, are a fantastic tool to have at our disposal. However, Traits can also be crutch for lazy programming. It’s very easy to just add a Trait to solve your immediate problem. Often composition is the better approach over inheritance or using a Trait.

What are typical situations for using Traits?

So what would be a typical situation when using a Trait would be a good idea?

Well, I think Traits are an excellent way to reuse a chunk of code between a set of similar classes that should not inherit from the same abstract class.

Using the social application from earlier, imagine we had objects for Post, Photo, Note, Message and Link. For the most part, these objects are fairly interchangeable within our system as they are typically created and interacted with between users.

However, Post, Photo, Note and Link are all objects that are publicly shareable between users, whereas Message objects are private messages that are not made public.

The Post, Photo, Note and Link objects all implement a Shareable interface:

interface Shareable {

  public function share();


Does it make sense to duplicate the share() method in every class that implements the Shareable interface?


Does it make sense to have an AbstractShare class that objects who implement the Shareable interface extend?


Does it make sense to have the share() method implemented as part of an AbstractEntity class, but then blocked out for the Message object?


Does it make sense to implement a ShareableTrait that fulfils the interface contract and can therefore be easily added to only objects that require it?


What is a real life example of using Traits?

When you first encounter Traits as another tool at your disposal, it can be difficult to know whether a situation should really call for using a Trait, or one of the many other possible solutions to solving this particular problem.

When you face this situation, I think it’s a really good idea to look to the world of Open Source to see how others have used this particular technique.

In my opinion, an Open Source project that makes good use of Traits is Laravel’s Cashier package.

The Cashier package adds functionality to your Eloquent models to make it really easy to manage subscriptions within your SaaS application.

However in order to add functionality to your existing models, you end up facing a predicament.

The first option is to simply implement the methods yourself by copy and pasting the method examples from the documentation. This isn’t a good solution because you might introduce bugs by copying the code incorrectly and whenever the Cashier package is updated you will have to go through all of your models and update your duplicated code.

A second object is to extend the Cashier object to inherit the methods that you need. This is also a bad solution because what happens if you want to add methods from a package that adds validation to your models? You will end up with a complicated lineage of inheritance that will make your code bloated and confusing when you, your colleagues, or your future self return to this code in the future.

Instead, the Cashier packages provides a Trait that allows you to add the functionality to any of models without duplicating the code yourself or having a nasty inheritance lineage:

use Laravel\Cashier\BillableTrait;
use Laravel\Cashier\BillableInterface;

class User extends Eloquent implements BillableInterface {

  use BillableTrait;

  protected $dates = ['trial_ends_at', 'subscription_ends_at'];


As similar excellent usage of a Trait is the Validating package also for Laravel’s Eloquent. This package allows you to create auto-validating models by including a Trait.

So as you can see, instead of extending the Cashier object to add the subscription methods, and then extending something like Magniloquent to add validation, you can simply add two Traits to your model. This prevents a crazy inheritance tree.


So the big question is, should you use Traits? I think you should definitely consider using Traits within your projects. Traits offer a really nice solution to the nasty mess of inheritance that can arise in single inheritance languages such as PHP.

Traits allow you to add functionality to your classes horizontally without over-complicating or duplicating code.

However, it is very easy to use Traits as a crutch. Traits are not the answer to all of your problems. Using a Trait in the wrong situation is most definitely a bad decision. If you are trying to crowbar the functionality you desire into a class using Traits, you are probably doing something wrong.

As with almost everything in computer programming, there is most definitely right and wrong situations to use certain components or patterns. A Trait might solve your immediate problem, but using composition might be the real answer to your predicament. Don’t look for situations to use Traits, instead try and choose the right tool from your tool belt when facing a problem. Understanding when and where to use Traits adds another weapon to your arsenal.

Philip Brown

Hey, I'm Philip Brown, a designer and developer from Durham, England. I create websites and web based applications from the ground up. In 2011 I founded a company called Yellow Flag. If you want to find out more about me, you can follow me on Twitter or Google Plus.

Join the Culttt

Become an insider and join the Culttt

  • Deacon

    Nice clear concise article, as ever!

    • No problem :) Glad you enjoyed it :D

      • John

        Hi Philip , your articles are great, the best I’ve found on laravel . I make a question. I need to convert a model dates. what would be the best way to define accesors and mutators for various fields generically.
        for example:
        class MyModel extends Eloquent {
        protected $dateFields = [‘dateOne’, ‘dateTwo’];
        foreach($dateFields as $dateField ) {
        ****this will never work, It is to illustrate the problem****
        public function get$dateFields[0]Attribute($value)
        return ucfirst($value);
        instead of:
        public function getDateOneAttribute($value)
        return ucfirst($value);

        thank you very much . regards

        • I think you would probably just have to define an accessor and mutator for each field.

  • menjaraz

    Very informative. Keep posting!

  • testy

    Man, I did not think the traits are so simple. Thank you! I can imagine that as @mixins in sass.

    • Yeah Traits are pretty cool :)

      • Joseph Rex

        Yea I thought of SASS mixins too when I saw this. It’s really awesome

  • Voodoo

    Nice article Philip :) I didn’t know the dwightwatson/validating package, seems good. For a large project would you suggest this trait based solution or a service one is still to be preferred?
    Thanks in advance! :)

    • I really like the validating package, I think it would work for both large and small projects. It really comes down to how you need to validate data.

    • Daniel LaBarge

      You may also like to consider http://github.com/esensi/model package which is a collection of traits for Eloquent models including watson/validating package.

  • npkatz

    re: Other drawbacks to using Traits are not being able to see all the methods of a class when looking at the source code as well as method conflicts or duplication of logic.

    I think it’s important to further emphasize, from a TDD standpoint, you should absolutely include a unit test for calling the trait functions(s) for “every” model that uses them. Otherwise, each model instance may have its own behavior that could break in the trait even though it’s not breaking in other models. Most hardcore TDD devs will already know this and might even discourage their team from using traits at all even though the alternatives are duplicate code or more complex inheritance or interfaces. There are many ways to hide code including not just traits but decorators, presenters, and proxies using things like PHP magic methods. All of these can be useful and efficient for coding but there’s no substitute for good code coverage in your tests.

    Personally I also see the advantage of the trait usage being that the function is only written once so there are not multiple instances of it floating around. The tighter the code the better. But as I said, it’s easy to ignore the fact that the function needs to be tested by every model that uses it.

    • Yeah absolutely, the trait should definitely be considered part of the concrete class and so should be unit tested appropriately :)

  • Pingback: Defining the building blocks of Domain Driven Design | Culttt()

  • Jeroen

    The way I use is for very small pieces of code that contain no business logic. I always combine them with an interface. I agree I could often just copy paste this code into my class, but I like this way of injecting code as it keeps the class clean. Some simple example:

    I have an interface: DiInitializerAware. If the DI container loads an object, and the object is Di Initializer Aware, it will check if an object has already been initialized and if not, it will run the initializers.

    Each class that is DiInitializerAware implements an IsInitializedInterface and IsInitializedTrait with methods isInitialized/setIsInitialized.

    I could of course write those functions in each class, it is not really difficult, but for me this isInitialized functionality is not the core of this class and if I can abstract it out, I like it.

    Regarding TDD, so far I have duplicated the test code, but it just occurs to me: how evil woul I be I have wrote a trait “IsInitializedTestTrait” to inject code in my test to test the functions included by the IsInitializedTrait? :P

    • Yeah that sounds like a good use of traits. I also tend to use interfaces and traits together.

      Hmm, well if you are confident that it won’t give your tests false positives, go for it :p

  • Pingback: How to create an Active Record style PHP SDK Part 15 | Culttt()

  • Nicolas Connault

    Typo in your 5th snippet, line 20 : “Socialable” instead of “Sociable” ;)

    I use traits in my Codeigniter project. I have two traits for my models: has_type and has_statuses, and they give my models a bunch of common methods for getting type info and assigning multiple statuses to different entity types.

    • Oops, nice catch Nicolas! Thank you :)

      Yeah Traits can really dry up your code!

  • Thanks Phil, this is one of the only articles I’ve seen with a real world example siting code from the Laravel framework. If you’d like a deeper real world example from soup to nuts have a read of my new article on traits. https://quickshiftin.com/blog/2014/11/php-traits

  • adib hanna

    Great article! really helped me to understand Traits better.

  • Manoj Neupane

    Awesome Post! Learnt a lot.

  • Ben

    Great article. I was reading about Traits in Laravels’s docs but I didn’t know what it was. After a Google search I came here and after reading your post I’m now aware of Traits and when/how to use them. Thanks!

    • Thanks Ben :) Glad it cleared things up for you!

  • Manu Phatak

    Good article! This was way easier to understand than the php.net docs. :D

  • 尤川豪

    Hey nice article!
    Yeah, thank you~!

  • Cristiano Garcia

    Very good, man! I’ve been looking for an article to help me understand what Traits are, but surely this post gave me more! Congratz!

  • Jakub Ciszak

    Great article. Thank You.

  • Elias Van Ootegem

    “Traits offer a nice solution to the nasty mess of inheritance”

    Really, I couldn’t disagree more. So much so that, because all I can find are posts praising traits as “a great addition”, I’ve felt compelled to blog about what I feel is wrong with the implementation of traits. Traits create a mess rather than reduce it, IMO. Traits have many bad, erm, traits which are equally important to highlightm which is what I’ve tried to do here: https://eliasvo.wordpress.com/2015/06/07/php-traits-if-they-werent-evil-theyd-be-funny/

    • Indeed, traits used in correctly can be a nightmare. But like any sharp tool, if you cut yourself it’s probably your own fault.

  • Why can’t the PHP documentation be written in human language like this? I get nothing when I read the PHP docs, but I get everything here.

    Thank’s a million for this succinct and highly informative piece of text.

  • Wow, nice article. Its been long since I had time to read your articles, and this one is just great. I remember when I started using classes in php I needed the multiple inheritance stuff, and not getting it I used abstract classes. I think the main disadvantage of using traits is like you said “not being able to see all the methods of a class when looking at the source code as well as method conflicts or duplication of logic.” . Well that can be very dangerous especially in large projects, so I guess programmers need to plan their code well before getting the fingers busy. But I admit, this feature is so cool. Thanks Phill.

    • Yes, very true Michael, when traits are used correctly they are a very powerful weapon in your arsenal, but it can also be very easy to get yourself into trouble!

      Glad you found it useful :)

  • mak

    It is great explanation @delalimichael:disqus.
    Thank you so much :)

    • No problem :)

      • mak

        Hey i wrote your name, dont know why it was showing Michael Azumah before.. Just edited it.
        Must be DIsQus Bug ;)

        Thank you so much @philip_brown:disqus

  • Ruchir kakkad

    It’s a great explanation.
    Thank you so much :)

  • Very Helpful and clear :)
    i just have a question can a trait itself extend from another class or implement an interface or not ?
    and can trait extends from another trait
    or its like a final class ?


    • Thank you :)

      Yes a trait can be extended, but you are getting into deep water when you start to do things like that. I would also try to keep things simple.

  • Dennis Snell

    Just found your article and I particularly appreciate your discussion around knowing which cases are suitable for traits versus best served via another pattern.

  • joynalabd

    Very informative article.