PHP Traits: Good or Bad?

In early March 2012, the PHP Group announced the release of PHP 5.4. Developer eagerly anticipated the release because of the many new features 5.4 would bring, the most sought after being traits. In the build up to the release, Shameer C wrote a fantastic overview of using traits in PHP, and I highly recommend reading Shameer’s article before this one because I assume you have a basic understanding of traits.

Traits have been generally accepted by the PHP development community, mainly because it’s a feature that exists in other programming languages like Java, C++, and Phython. Additionally, the benefits of traits have been widely touted, with developers giving their own two cents on how traits can benefit any project, especially as a replacement for OOP inheritance. But are traits actually that good? Are they a feature which will help raise the level of PHP development, or are they just a fad?

PHP Traits are Bad

On the surface, there is strong support for PHP traits because using them can help reduce code duplication throughout your application. In addition, they can help improve maintainability and the cleanliness of your code.

Traits are certainly welcomed, but many leading developers fear they may be used in ways that were never intended. Anthony Ferrara is one such developer, with his fear going so far as to contemplate the possibility of traits becoming the next most abused feature alongside eval and constants. But before Anthony makes his case, he raises a very interesting point: traits are actually a collection of specific mixins, which essentially don’t have state. PHP’s implementation of traits does allow states to be used, and therefore traits in PHP are actually mixins. This simple fact questions the true intent of PHP traits as ultimately they are flying under a false flag. There is no explanation regarding why traits are actually processed as mixins rather than the globally-acknowledged stateless mixins they should be.

Anthony continues, citing that traits are very close in functionality to what extends allow us to with regard to coupling classes together. With extends being a well-respected and long-used feature, it is only fair to ask whether traits truly have a place in PHP or are they trying to stand atop the shoulders of existing features in an attempt to look tall?

Then there’s also the question of interfaces. Many developers have only a vague idea about what the real difference is between interfaces and traits; their ability to be reused is very similar, and the inheritance depth possible with them is also very similar. Are traits actually something new to PHP, or are they really just an upgrade to interfaces?

PHP Traits are Good

Regardless of the unanswered questions, traits are great for PHP, allowing us to create multiple inheritance scenarios (extends only supports single inheritance).

Single inheritance has been used for many years now and comes part and parcel with object orientated programming in PHP, which has restricted advanced programmers from developing complex systems while keeping code clean and to a minimum. In other languages, multiple inheritance could be used to eliminate duplicate code in such situations. But multiple inheritance isn’t possible in PHP. Interfaces are instead offered as a substitute, and an unsuccessful one at that.

Interfaces are not intended to be used in this way, rather to act as contracts which force any classes that implement it to deliver its functionality. This can help open up the coupling of classes and methods, but doesn’t offer a true substitute multiple inheritance in PHP.

A few developers have attempted to create some creative solutions for multiple inheritance in PHP, but many are bloated, making the overall result redundant and more of an experiment than a practical solution.

With traits, multiple inheritance can be implemented naturally using ingenious systems. As Shameer showed in his introduction to traits, you can create multiple traits inside classes. John Squibb uses the multiple traits to create a multiple inheritance environment in his 2011 example.

Many programmers think multiple inheritance is evil citing the Diamond Problem, and claim single inheritance provides less headaches. The fact of the matter with PHP isn’t the practicality of implementing multiple inheritance but rather the symbolism that comes with the possibility of implementing multiple inheritance. This has become ever more important in light of many of the programming public stating their dislike for PHP, evident if you google “don’t use PHP”. With the possibility of multiple inheritance, PHP becomes a more challenging, more expressive, and more acceptable programming language, rather than just the “most common web language”. I find this incredibly comforting when Java, Python, or C++ programmers try to dismiss PHP because of its lack of support of standardized programming methods across languages.

Traits are a true indication that PHP is slowly and surely become a language which will embrace more and more standard programming techniques, hopefully winning over many more established programmers and developers.

Conclusion

Traits allow PHP developers to create cleaner, simpler, and more efficient code while also allowing more complex systems to be made and experimented with.
They’re not good; they are fantastic! They open up another level of development techniques to OOP programmers using PHP, and I believe they are a sign of things to come in future PHP versions.

For more information on the topics mentioned in this article, including a low down on traits themselves, please see the following links:

Image via Fotolia

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://blog.ircmaxell.com ircmaxell

    So you bring up my post, and that I think they are going to be abused. Then you don’t argue any of the points that I made, but conclude that traits are awesome… How did you get from A to B? What about the points I raised in my article as to *why* specifically traits are a problem (and it goes deeper than confusing terminology).

    What about the tight static coupling that they represent? What about the inherent lack of testability? What about Single Responsibility violations?

    It’s not that traits are useless. It’s that most problems that developers are actively reaching for them to use are usually better solved through a compositional design pattern. Inheritance leads to tight coupling of functionality. If traits were composable at runtime (like they are in Scala), then I’d be fine with them. But seeing as they are only composable at compile time, it yields tight static coupling… Which is an enemy of OOP…

    • http://www.callumeuanhopkins.co.uk/ Callum Hopkins

      @ircmaxell Sorry that you feel I’ve ignored the points you make in your article but I left them out and included a link to your article so I wouldn’t be copying the points you’ve raised in your great article. Many writers get annoyed when their article is basically lifted from their site and placed in another article, so I left the points out so hopefully readers would head over to your blog to read your article and their points in full.

      @leviMorrison It does make it more challenging. However overall Traits, in my opinion, are a positive thing, especially as a flagship for the type of features that are hopefully going to appear in future versions of PHP. Apologies if the article seems confusing on this stance.

  • Levi Morrison

    In your conclusion you claim that traits allow you to create simpler code, but farther up on the page you say that it makes it more challenging. Regardless of my stance on traits, you are submitting conflicting ideas.

  • http://gonzalo123.com/ Gonzalo Ayuso

    IMHO the real question isn’t “traits are good or not”. The real question is “inheritance is good or not”. If the answer to the second question is yes, then traits are good, or even better, because they allow us to create more reusable components and flexible. If the answer is no, then traits are as bad as extended classes. Extended classes help reusing code, but they have an insane trend to become a hotchpotch and to violate the Liskov substitution principle (the L in SOLID principle).

    Today I prefer to use Traits rather than single inheritance with classes. But if can, I avoid to use them with the Dependency Injection.

    • http://datavirtue.com Sean Anderson

      Good point. I think it is good advice to avoid inheritance and just use traits with PHP. It should result in cleaner code and logic. Like.

  • http://www.aheado.de Harry D.

    The article is inspiring and has everything included, pro and contra. Thank you for that. :)

    From my point of view traits are more comfortable to use and avoids workarounds and more complex compositions of classes. But I don’t think they are a general purpose solution. Traits may lead to overusage like any comfortable pattern in software development. In the end it is up to the developer to decide what to use. Sometimes we all forget that software development is not done because it is possible but to solve problems. If a trait solve a problem in a specific environment then I welcome it as another tool I can use.

    About being able to test traits I believe it is not an error of the language. Instead testframeworks should improve to provide proper ways to test traits. I don’t know about Java but I am pretty sure that they found ways to test traits.

    The static binding is not really a problem if you use traits in an OOP way. What I can imagine is that a trait would ask a factory what to deliver to the class and use a fallback inside the trait if nothing specific is found. Or alternatively use a strategy pattern which decides on the loaded class what to do.

    On the other hand a trait can be seen as a more powerful function. If I had to implement something like a trait without having traits available then it could be similiar to this:

    function traitHello() {
    return “Hello”;
    }
    class test {
    public function __call() {
    // some code to detect the trait function
    return traitHello();
    // some other alternatives etc.
    }
    }
    $obj = new test();
    $text = $obj->traitHello();
    echo $text; // output “Hello”

    The only problem would be in this small example that you would have to pass the object to the function to get access to the properties and methods if you need them.

    That’s why I think traits are indeed comfortable if you know what you do.

  • http://datavirtue.com Sean Anderson

    Can we have our cake and eat it too? Simplicity often brings ease of use at the expense of power and flexibility. Whereas the OOP semantics of PHP are simple, they lack in such a serious way as to necessitate a hack like traits (if one wishes to stick with PHP). With power comes complexity and in the case of traits, while being very useful and potentially elegant, they will definitely be overused/misused. Hardly surprising, this reflects the problems that occur with widespread use of C++ and the reason other languages were developed which try to capture the power while eliminating complexity (Java). Technology always seems to undulate between complex to simple and back again (C#).

  • John

    Please improve your site’s search functionality. stuff is good, but hard to navigate and searching stuff.