Copied from wiki.php.net, last synchronized Oct 13, 2026 11:49 UTC
Associative arrays often repeat a key and a variable with the same name. This RFC proposes :$name as shorthand for “name” => $name in array construction and destructuring:
<?php
$x = 10;
$y = 20;
$point = [:$x, :$y]; // $point = ['x' => $x, 'y' => $y]
[:$x, :$y] = $point; // ['x' => $x, 'y' => $y] = $point
$point = array(:$x, :$y); // array('x' => $x, 'y' => $y)
list(:$x, :$y) = $point; // list('x' => $x, 'y' => $y) = $point
?>
An array element written :$name is equivalent to “name” => $name. The key is the exact, case-sensitive variable name without the leading $. This applies to both array constructors ([] and array()) and destructuring patterns ([] and list()). In construction, the variable is read; in destructuring, the value at that key is assigned to the variable. All existing behavior of an explicit keyed element applies, including duplicate keys and missing-key warnings.
Here, $name means one directly named variable token (T_VARIABLE). The shorthand does not accept variable variables, array dimensions, object or static properties, or arbitrary expressions: :$$name, :$name[0], and :$object->name are invalid. For those values, write an explicit key, for example [“name” => $object->name].
Whitespace after : is allowed. This includes an ASCII space, tab (\t), line feed (\n), and carriage return (\r). Comments may also appear between : and the variable.
The identifier determines both the variable and its string key preserving case exactly.
The shorthand works at any nesting level and in destructuring patterns used by foreach. It adds an array-element form but not a function-argument form. foo(:$name) is invalid. array() and list() are language constructs with array-element syntax, so they are included alongside their [] equivalents.
An array can mix the shorthand with explicit keys:
<?php
$name = 'Weilin';
$age = 26;
$user = ['id' => 1, :$name, :$age];
// ['id' => 1, 'name' => 'Weilin', 'age' => 26]
?>
The shorthand also works beside positional elements and unpacking:
<?php
$name = 'Weilin';
$values = [10, 20];
$result = [...$values, :$name,];
// [0 => 10, 1 => 20, 'name' => 'Weilin']
?>
The shorthand can also be mixed with explicit keys when destructuring:
<?php
$user = ['name' => 'Weilin', 'age' => 26];
[:$name, 'age' => $years] = $user;
// $name === 'Weilin'; $years === 26
?>
The same keyed targets work with list():
<?php
$user = ['name' => 'Weilin', 'age' => 26];
list(:$name, 'age' => $years) = $user;
// $name === 'Weilin'; $years === 26
?>
An object implementing ArrayAccess can be destructured by key, as with an explicit keyed element. This reads an array offset, not an object property:
<?php
$object = new ArrayObject(['name' => 'Ada']);
[:$name] = $object; // Equivalent to ['name' => $name] = $object
echo $name; // Ada
list(:$name) = $object;
echo $name; // Ada
?>
Here is an example in a foreach loop:
<?php
$rows = [['name' => 'Weilin']];
foreach ($rows as [:$name]) {
echo $name; // Weilin
}
?>
The long forms support the same shorthand, including foreach destructuring:
<?php
$name = 'Weilin';
$user = array('id' => 1, :$name); // array('id' => 1, 'name' => 'Weilin')
list(:$name) = $user; // $name === 'Weilin'
foreach (array($user) as list(:$name)) {
echo $name; // Weilin
}
?>
Nested construction and destructuring work in the same way:
<?php
$name = 'Weilin';
$record = ['user' => array(:$name)];
// ['user' => ['name' => 'Weilin']]
['user' => [:$name]] = $record;
echo $name; // Weilin
?>
A valid nested pattern uses list() at both levels:
<?php
$record = ['user' => ['name' => 'Ada']];
list('user' => list(:$name)) = $record;
echo $name; // Ada
?>
You cannot mix [] with list() within one nested destructuring pattern. This is an existing restriction, including when no shorthand is used:
<?php
$record = ['user' => ['name' => 'Ada']];
['user' => [:$name]] = $record; // Valid
list('user' => list(:$name)) = $record; // Valid
list('user' => [:$name]) = $record; // Invalid: cannot mix list() and []
?>
You cannot mix keyed and unkeyed elements at the same level of a destructuring pattern. This also applies without the shorthand. Array construction can still mix them:
<?php
$name = 'Weilin';
$age = 26;
$user = [$age, :$name]; // Valid construction: [0 => 26, 'name' => 'Weilin']
[:$name, $age] = $user; // Invalid: keyed and unkeyed at the same level
?>
<?php
$name = 'new';
$first = ['name' => 'old', :$name]; // ['name' => 'new']
$second = [:$name, 'name' => 'later']; // ['name' => 'later']
?>
When array unpacking and the shorthand produce the same string key, the later element wins:
<?php
$name = 'new';
$first = [...['name' => 'old'], :$name]; // ['name' => 'new']
$second = [:$name, ...['name' => 'later']]; // ['name' => 'later']
?>
<?php
[:$name] = []; // Warning: Undefined array key "name"
var_dump($name); // NULL
?>
Each of these shorthand forms is invalid; the last line shows the explicit-key alternative:
<?php
[:$$name]; // Invalid: variable variable
[:$name[0]]; // Invalid: array dimension
[:$object->name]; // Invalid: object property
[:$class::$property]; // Invalid: static property
[:($name)]; // Invalid: expression
['name' => $object->name]; // Valid
?>
<?php
$Name = 'upper';
$name = 'lower';
echo json_encode([: $Name, :$name]); // {"Name":"upper","name":"lower"}
$array = [: /* key from the variable name */ $name]; // ['name' => 'lower']
?>
Construction reads the variable normally, including its warning if it has not been defined:
<?php
$array = [:$missing]; // Warning: Undefined variable $missing
// ['missing' => null]
?>
When constructing an array, [:$name] does not create a new reference to the original variable. A reference requires the existing explicit-key form:
<?php
$name = 'before';
$byValue = [:$name];
$byReference = ['name' => &$name];
$name = 'after';
echo $byValue['name']; // before
echo $byReference['name']; // after
// [:&$name] is invalid.
?>
When destructuring, assignment to $name follows ordinary assignment. If $name is already a reference, the value it points to is overwritten:
<?php
$target = 'before';
$name =& $target;
[:$name] = ['name' => 'after'];
echo $target; // after
?>
None. The proposed syntax is currently invalid.
PHP 8.7.
Static analyzers must recognize the new element form in [], array(), and list().
None.
None.
None.
Shorthand in function calls is outside this RFC.
TBD. Not in the voting process.
The draft implementation and PHPT tests are available at php-src PR #24034.
See draft implementation in php-src PR #24034.
An earlier equals-sign prefix was replaced with :$name.
array() and list() and specified which variables qualify.:$name and added ArrayAccess and unpacking examples.