list
Destructures an array into several separate variables in a single assignment.
list(mixed $var, mixed ...$vars = ?): arrayParameters
| Parameter | Type | Description |
|---|---|---|
$var | mixed | A variable to assign the first element to. May itself be a nested list() or [] pattern, or be prefixed with a key as 'key' => $var. |
$varsoptional | mixed | Further variables to assign the remaining elements to. A slot may be left empty to skip that element. |
Return value
arrayReturns the array that was assigned, so assignments can be chained.
Errors
Unpacking a scalar or a string emits a warning ("Cannot use int as array", "Cannot use string as array") and leaves every target variable null — strings cannot be destructured at all — while unpacking null assigns null silently. Unpacking an object that does not implement ArrayAccess is not a warning: it throws Error: Cannot use object of type X as array.
Changelog
- PHP 7.3.0Reference assignments in array destructuring are supported, e.g. [&$a, &$b] = $arr.
- PHP 7.1.0Keys may be specified, which allows destructuring associative arrays and arrays with non-sequential keys.
- PHP 7.1.0The short syntax [$a, $b] = $arr became available as an equivalent of list().
list() pulls values out of an array and assigns them to variables in one statement. Since PHP 7.1 the short form [$a, $b] = $arr does exactly the same thing and is what most modern code uses; list() stays valid and is still everywhere in older codebases.
It earns its place when a function returns several values as an array, when looping over rows from a CSV or a query, and when you want named variables out of a small record. Inside a loop you can destructure each row directly with foreach ($rows as [$id, $name]).
Positions, gaps, keys and nesting
By default assignment goes by position: index 0 to the first variable, 1 to the second, and so on. Leaving a slot empty skips an element, as in list($a, , $c). Since PHP 7.1 you can name keys instead, which is the only reliable way to destructure an associative array, and the order you write them in does not matter. Patterns nest, so [$x, [$y, $z]] works on nested arrays, and since PHP 7.3 a target can be bound by reference with &.
Because list() is a language construct rather than a function, you cannot pass it as a callable or call it dynamically.
Example
When to use it
- Unpack a function's multi-value return, such as [$ok, $error] = validate($input).
- Split each CSV line into named variables inside a foreach loop.
- Swap two variables without a temporary: [$a, $b] = [$b, $a].
- Pull just the id and name out of a database row keyed by column name.
Frequently asked questions
What is the difference between list() and the [] short syntax?
Nothing functional since PHP 7.1 — [$a, $b] = $arr and list($a, $b) = $arr compile to the same thing. The short form is preferred in new code and is the only one that reads naturally in a foreach.
Can list() destructure an associative array?
Yes, since PHP 7.1, using the keyed form ['id' => $id, 'name' => $name] = $row. Without keys, list() looks for the integer keys 0, 1, 2 and will not find named columns.
Why are my list() variables null?
Almost always because the source array does not have sequential integer keys starting at 0 — for example it came from a query keyed by column name, or from array_filter which preserves keys. Use the keyed form, or run the array through array_values() first.
More examples
Skipping elements and swapping variables
Prints "B A" then "one three". The swap works because the right-hand array is fully built before any assignment happens, so no temporary variable is needed. The empty slot in the second list() discards 'two'.
<?php
$left = 'A';
$right = 'B';
[$left, $right] = [$right, $left];
echo "$left $right\n";
list($first, , $third) = ['one', 'two', 'three'];
echo "$first $third\n";Nested destructuring in a foreach
Prints "p1: x=1 y=2" and "p2: x=3 y=4". The pattern mirrors the shape of each row, so the inner array is unpacked in the same statement — no second assignment inside the loop body.
<?php
$points = [
['p1', [1, 2]],
['p2', [3, 4]],
];
foreach ($points as [$label, [$x, $y]]) {
echo "$label: x=$x y=$y\n";
}Keyed versus positional
Both print "7: Ada". The keyed form matches by key, so writing name before id changes nothing. The positional form on the second array works only because its keys really are 0 and 1 — running it against $row would produce nulls and warnings.
<?php
$row = ['id' => 7, 'name' => 'Ada'];
['name' => $name, 'id' => $id] = $row;
echo "$id: $name\n";
$list = [7, 'Ada'];
[$id2, $name2] = $list;
echo "$id2: $name2\n";
Discussion