14

Dec 11

Traits: PHP 5.4’s Must Have Feature

The upcoming release of PHP 5.4 will contain a feature that for many will make the decision to upgrade a no-brainer. This feature called Traits is a mechanism for horizontal code reuse that provides a way for a set of methods to be used by multiple classes in independent class hierarchies. Traits gives developers a way to design code blocks that can be plugged into any class at compile time. This mitigates many of the limitations of a single inheritance model.

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 one class into another, 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. I see Traits making code easier to maintain, not only because it simplifies reuse in a number of contexts, but also because it will be easier to test code included at compile time.

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 language features with minor releases – or maybe these point releases shouldn’t be thought of as minor releases at all.

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

14

Aug 09

Expand an array into function arguments with call_user_func_array

call_user_func_array is a time saving, though not commonly used function that allows you to treat the items of an array as arguments when calling a function. You indicate which function call_user_func_array is to call with the first argument, which can take two or three forms, depending on whether you’re using a version of PHP greater or equal to 5.3.

In it’s first form, you supply a function name as the first argument.

function sum(x, y, z) {
    return x + y + z;
} 
 
$arr = array(1, 3, 5);
echo call_user_func_array('sum', $arr);    // prints 9

In the second form, you pass an array containing an object reference and the name of a method as the first argument. The following would call $obj->sum.

echo call_user_func_array(array($obj, 'sum'), $arr);

The third form involves the use of a lambda, and so it only works with versions of PHP >= 5.3. In this form you simply define the lambda, and use its reference as the first parameter.

$func = function(x, y, z) {
    return x + y + z;
}
$arr = array(5, 2, 7);
echo call_user_func_array($func, $arr);    // prints 14