PHP - Splat Operator

Since PHP 5.6, you can use splat operator (...) to create simpler variadic functions (functions that take an undefined number of arguments). To demonstrate this, the code snippet below provides a function that will return the sum of any number of numbers:

function adder(...$numbers)
{
    $sum = 0;

    foreach ($numbers as $number)
    {
        $sum += $number;
    }

    return $sum;
}

// Both of these work.
adder(1,2);
adder(1,2,3,4,5,6,7);

Variadic functions have been around since before 5.6 but only now can you use the splat operator to simplify them instead of relying on func_get_args().

Don't get carried away though. Only the last parameter can use the splat operator, so the following won't work as much as I would like it to.

...

function adder(ItemType1 ...$adds, ItemType2 ...$subs)
{
    $sum = 0;

    foreach ($adds as $add)
    {
        $sum += $add->getCargo();;
    }

    foreach ($subs as $sub)
    {
        $sum -= $sub->getCargo();
    }

    return $sum;
}

Argument Unpacking

You can also use the splat operator to perform the reverse when passing in arguments to a function. We call this argument unpacking. Here is an example:

function adder($arg1, $arg2)
{
    return $arg1 + $arg2;
}

$args = array(1,2);
print adder(...$args); // outputs 3

Array of Objects Validation

This is a neat tip provided by a talk on extremely defensive PHP which makes use of principles just described to validate that every element provided in an array is of a certain type.

class WagonCollection
{
    private $m_wagons;

    public function __construct(array $wagons) 
    {
        $this->m_wagons = (function (Wagon ...$wagons) {
            return $wagons;
        })(...$wagons);
    }
}

As you can see, we define an anonymous variadic function on line 7, that can take any number of Wagon objects as parameters, before immediately calling that function with unpacking of the passed in $wagons array. Thus, if any single element in the $wagons array is not a Wagon, this will throw an error.

It's a shame that we can't just use generics, or even some kind of fancy typehint, so this will have to suffice until we can. If you want to try something crazy, you could check this out.

References

Author

Programster

Stuart is a software developer with a passion for Linux and open source projects.

comments powered by Disqus
We are a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for us to earn fees by linking to Amazon.com and affiliated sites. More info.