Programster's Blog

Tutorials focusing on Linux, programming, and open-source

PHP - Splat Operator

PHP

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

Last updated: 16th September 2021
First published: 16th August 2018

This blog is created by Stuart Page

I'm a freelance web developer and technology consultant based in Surrey, UK, with over 10 years experience in web development, DevOps, Linux Administration, and IT solutions.

Need support with your infrastructure or web services?

Get in touch