What is the meaning of three dots (...) in PHP?

PhpSyntaxOperators

Php Problem Overview


While I am installing Magento 2 on my Server, I got an error. After investigating the code and found that there is are three dots (...), which is producing the error. I included the code I found below:

return new $type(...array_values($args));

What is this operator called, and what is its purpose?

Php Solutions


Solution 1 - Php

This is literally called the ... operator in PHP, but is known as the splat operator from other languages. From a 2014 LornaJane blog post on the feature:

> This feature allows you to capture a variable number of arguments to a function, combined with "normal" arguments passed in if you like. It's easiest to see with an example: > > function concatenate($transform, ...$strings) { > $string = ''; > foreach($strings as $piece) { > $string .= $piece; > } > return($transform($string)); } > > echo concatenate("strtoupper", "I'd ", "like ", 4 + 2, " apples");

(This would print I'D LIKE 6 APPLES)

> The parameters list in the function declaration has the ... operator in it, and it basically means " ... and everything else should go into $strings". You can pass 2 or more arguments into this function and the second and subsequent ones will be added to the $strings array, ready to be used.

Solution 2 - Php

There are TWO uses for the ellipsis (...) PHP token—think of them as packing an array and unpacking an array. Both purposes apply to function arguments.


Pack

When defining a function, if you need a dynamic number of variables provided to the function (i.e., you don't know how many arguments will be provided to that function when called in your code) use the ellipsis (...) token to capture all remaining arguments provided to that function into an array that is accessible inside the function block. The number of dynamic arguments captured by ellipsis (...) can be zero or more.

For example:

// function definition
function sum (...$numbers) { // use ellipsis token when defining function
    $acc = 0;
    foreach ($numbers as $nn) {
        $acc += $nn;
    }
    return $acc;
}

// call the function
echo sum(1, 2, 3, 4); // provide any number of arguments

> 10

// and again...
echo sum(1, 2, 3, 4, 5);

> 15

// and again...
echo sum();

> 0

When packing is used in function instantiation, ellipsis (...) captures all remaining arguments, i.e., you can still have any number of initial, fixed (positional) arguments:

function sum ($first, $second, ...$remaining_numbers) {
    $acc = $first + $second;
    foreach ($remaining_numbers as $nn) {
        $acc += $nn;
    }
    return $acc;
}

// call the function
echo sum(1, 2); // provide at least two arguments

> 3

// and again...
echo sum(1, 2, 3, 4); // first two are assigned to fixed arguments, the rest get "packed"

> 10

Unpack

Alternatively, when calling a function, if the arguments you provide to that function are previously combined into an array use the ellipsis (...) token to convert that array into individual arguments provided to the function—each array element is assigned to the respective function argument variable named in the function definition.

For example:

function add ($aa, $bb, $cc) {
    return $aa + $bb + $cc;
}

$arr = [1, 2, 3];
echo add(...$arr); // use ellipsis token when calling function

> 6

$first = 1;
$arr = [2, 3];
echo add($first, ...$arr); // used with positional arguments

> 6

$first = 1;
$arr = [2, 3, 4, 5]; // array can be "oversized"
echo add($first, ...$arr); // remaining elements are ignored

> 6

Unpacking is particularly useful when using array functions to manipulate arrays or variables.

For example, unpacking the result of array_slice:

function echoTwo ($one, $two) {
    echo "$one\n$two";
}

$steaks = array('ribeye', 'kc strip', 't-bone', 'sirloin', 'chuck');

// array_slice returns an array, but ellipsis unpacks it into function arguments
echoTwo(...array_slice($steaks, -2)); // return last two elements in array

> sirloin
> chuck

Solution 3 - Php

Every answer refers to the same blog post, besides them, here is the official documentation about variable-length argument lists:

http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list

> In PHP 5.6 and later, argument lists may include the ... token to denote that the function accepts a variable number of arguments. The arguments will be passed into the given variable as an array

It seems "splat" operator is not an official name, still it's cute!

Solution 4 - Php

In PHP 7.4 the ellipsis is also the Spread operator:

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];

Source: https://wiki.php.net/rfc/spread_operator_for_array

Solution 5 - Php

To use this feature, just warn PHP that it needs to unpack the array into variables using the ... operator. See here for more details, a simple example could look like this:

$email[] = "Hi there";
$email[] = "Thanks for registering, hope you like it";

mail("[email protected]", ...$email);

Solution 6 - Php

Meaning is that it decomposes an associative array to a list. So you do not need to type N parameters to call a method, just one. If method allows a decomposed parameter and if parameters are of the same type.

For me, the most important thing about splat operator is that it can help to typehint array parameters:

$items = [
    new Item(), 
    new Item()
];

$collection = new ItemCollection();
$collection->add(...$items); // !

// what works as well:
// $collection->add(new Item());
// $collection->add(new Item(), new Item(), new Item()); // :(

class Item  {};
 
class ItemCollection {
    
    /**
     * @var Item[]
     */
    protected $items = [];
    
    public function add(Item ...$items)
    {
        foreach ($items as &$item) {
            $this->items[] = $item;
        }
    }
} 

it saves some effort on type control, especially while working with huge collections or very object-oriented.

Important to notice is that ...$array do decompose an array despite the type of its items, so you can go the ugly way also:

function test(string $a, int $i) {
    echo sprintf('%s way as well', $a);
    
    if ($i === 1) {
        echo('!');
    }
}

$params = [
    (string) 'Ugly',
    (int) 1
];

test(...$params);

// Output:
// Ugly way as well!

But please don't.

Solution 7 - Php

This is the so called "splat" operator. Basically that thing translates to "any number of arguments"; introduced with PHP 5.6

See here for further details.

Solution 8 - Php

In PHP 8.1, this syntax "(...)" is used as a new way to create callables.

Before PHP 8.1:

$callable = [$this, 'myMethod'];

After PHP 8.1:

$callable = $this->myMethod(...);

Source: https://wiki.php.net/rfc/first_class_callable_syntax

Solution 9 - Php

It seems no one has mentioned it, so here to stay[It will also help Google (& Other SEs) guide devs who asking for Rest Parameters in PHP]:

As indicated here its called Rest Parameters on JS & I prefer this meaningful naming over that splat thing!

In PHP, The functionality provided by ...args is called Variadic functions which's introduced on PHP5.6. Same functionality was used to be implemented using func_get_args().

In order to use it properly, you should use rest parameters syntax, anywhere it helps reducing boilerplate code.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionabu abuView Question on Stackoverflow
Solution 1 - PhpSaumya RastogiView Answer on Stackoverflow
Solution 2 - PhpbloodyKnucklesView Answer on Stackoverflow
Solution 3 - Phprap-2-hView Answer on Stackoverflow
Solution 4 - PhpjawiraView Answer on Stackoverflow
Solution 5 - PhpMahendra JellaView Answer on Stackoverflow
Solution 6 - PhpyergoView Answer on Stackoverflow
Solution 7 - PhpGhostCatView Answer on Stackoverflow
Solution 8 - PhpjawiraView Answer on Stackoverflow
Solution 9 - PhpBehradKhodayarView Answer on Stackoverflow