Traits: PHP 5.4’s Must Have Feature

PHP 5.4’s most anticipated feature “Traits” is a mechanism for horizontal code re-use that provides a way to include a set of methods in multiple classes at compile time. Why do we need an alternative to composition, our current mechanism for horizontal code re-use? The problem with composition is that everything happens at run-time, and whenever we use composition, we create a dependency that must be managed. When we attach a Trait to a class, it becomes a part of that class, the way a parent class is a part of its child, only the relationship is not hierarchical. This means that methods that are attached to a class with Traits can be tested like any other method in the class.

The essential characteristics of Traits are these: they are blocks of code that cannot be instantiated, they have a mechanism for controlling visibility and resolving conflict, and they can be nested. That is, a Trait may be composed partially or entirely of other Traits. Let’s take a look at the particulars of these features.

A developer begins by defining methods in a block preceded by the keyword “trait” and an identifier. Once you’ve defined a trait, you import its methods into a class with the keyword “use” followed by the trait name. You can import more than one trait per “use” statement by including multiple trait names separated by commas. Additionally, you can can limit which methods are imported by defining a block following the trait names. The traits feature includes conflict detection, and syntax for indicating which methods to use when you attempt to use more than one trait with the same method. Here is an example:

trait bigBar {
    public function toString() {
        return implode(', ', $this->_data);
    }
    public bar() {
        return 'Big ' . $this->_bar;
    }
}
 
trait littleBar {
    public bar() {
        return 'Little ' . $this->_bar;
   }
}
 
class foo {
    use bigBar, littleBar {
        bigBar::bar;
        littleBar::bar as smallBar;
    }
}

The first line inside the “use” block resolves the conflict between the bar methods present in both traits. The second line renames littleBar’s “bar” method to smallBar. This makes it possible to use both “bar” methods.

I can imagine horizontal code reuse being messy if one were allowed to import methods from any class into any other class, but the syntax of Traits ensures that developers only use components that are designed for reuse, rather than piecing them together from a variety of sources. Traits will make code easier to maintain, not only because it simplifies re-use in a number of contexts, but also because it simplifies testing.

This is the second minor release of PHP that has added the kind of language features that are commonly associated with major releases. Version 5.3 introduced both namespaces and lambdas, and with the addition of Traits, PHP has gained three truly groundbreaking features in two minor version updates. It will be interesting to see whether the PHP team continues to add major language features with minor releases.

You can read more about Traits here:
https://wiki.php.net/rfc/horizontalreuse

Leave a comment