Destructuring and Spread

Destructuring unpacks an array into separate variables in one statement. The spread operator ... does the opposite: it expands an array into a list of elements or arguments. Together they make code that handles rows, pairs and lists of arguments much shorter and clearer.

Destructuring lists

Put variables in square brackets on the left of an assignment, and the array's elements are assigned to them in order:

PHP
<?php

$point = [3, 7];
[$x, $y] = $point;
echo "x=$x y=$y\n";

[$first, , $third] = ["a", "b", "c"];      // skip an element
echo "$first $third\n";

$a = 1;
$b = 2;
[$a, $b] = [$b, $a];                        // swap
echo "$a $b\n";
Output
x=3 y=7
a c
2 1

The older list($x, $y) = $point; syntax does the same thing.

Destructuring by key

For associative arrays, name the keys you want. Order doesn't matter, and you can take only some of them:

PHP
<?php

$user = ["id" => 42, "name" => "Ana", "email" => "ana@example.com", "role" => "admin"];

["name" => $name, "role" => $role] = $user;
echo "$name is an $role\n";
Output
Ana is an admin

Destructuring in foreach

Unpacking each row right in the loop header is one of the most useful forms:

PHP
<?php

$cart = [
    ["Pen", 1.20, 10],
    ["Notebook", 3.50, 4],
];
foreach ($cart as [$item, $price, $qty]) {
    printf("%-9s %2d x %.2f\n", $item, $qty, $price);
}

$people = [["name" => "Ana", "age" => 34], ["name" => "Ben", "age" => 27]];
foreach ($people as ["name" => $n, "age" => $a]) {
    echo "$n ($a)\n";
}
Output
Pen       10 x 1.20
Notebook   4 x 3.50
Ana (34)
Ben (27)

Returning several values

A function can return an array, and the caller can destructure it immediately:

PHP
<?php

function minMax(array $values): array
{
    return [min($values), max($values)];
}

function parseName(string $full): array
{
    $parts = explode(" ", $full, 2);
    return ["first" => $parts[0], "last" => $parts[1] ?? ""];
}

[$lo, $hi] = minMax([14, 9, 21, 17, 6]);
echo "min $lo, max $hi\n";

["first" => $f, "last" => $l] = parseName("Grace Brewster Hopper");
echo "$l, $f\n";
Output
min 6, max 21
Brewster Hopper, Grace

Nested destructuring

PHP
<?php

$line = ["from" => [0, 0], "to" => [3, 4]];
["from" => [$x1, $y1], "to" => [$x2, $y2]] = $line;
echo sqrt(($x2 - $x1) ** 2 + ($y2 - $y1) ** 2), "\n";
Output
5

Missing elements

If the array is shorter than the pattern, the extra variables become null with a warning. Check the length first, or pad the array:

PHP
<?php

[$a, $b] = array_pad(explode(":", "host"), 2, "80");
echo "$a $b\n";

[$c, $d] = explode(":", "host");
Output
host 80

Warning: Undefined array key 1 in main.php on line 6

The spread operator in arrays

...$array inside an array literal inserts all of its elements. It works with string keys too (later keys win, like array_merge):

PHP
<?php

$low = [1, 2, 3];
$high = [8, 9];

$all = [0, ...$low, 5, ...$high];
echo implode(", ", $all), "\n";

$defaults = ["theme" => "light", "size" => 14];
$settings = [...$defaults, "size" => 16, "lang" => "pt"];
print_r($settings);
Output
0, 1, 2, 3, 5, 8, 9
Array
(
    [theme] => light
    [size] => 16
    [lang] => pt
)

Spreading arguments

When calling a function, ...$args passes each element as a separate argument. With string keys, they become named arguments (lesson 28):

PHP
<?php

function volume(float $length, float $width, float $height): float
{
    return $length * $width * $height;
}

$dims = [2, 3, 4];
echo volume(...$dims), "\n";
echo max(...[3, 9, 4]), "\n";

$named = ["height" => 10, "length" => 1, "width" => 2];
echo volume(...$named), "\n";
Output
24
9
20

Collecting arguments: variadic functions

The same three dots in a function's parameter list collect any number of arguments into an array:

PHP
<?php

function average(float ...$numbers): float
{
    return $numbers === [] ? 0 : array_sum($numbers) / count($numbers);
}

echo average(4, 8, 15, 16, 23, 42), "\n";
echo average(), "\n";

$data = [1, 2, 3];
echo average(...$data), "\n";
Output
18
0
2

Try it yourself

Parse lines of "name,city,score" with explode and destructuring, then print a summary.

Try it yourself · main.php
Edit the code, copy it into main.php, then run it with php main.php (PHP 8.5). How to install PHP
Output
Ana from Lisbon scored 82
Ben from Leeds scored 91
Cleo from Lisbon scored 77
Best 91, worst 77