Adds the possibility to extend values with type declarations while using array or list destructuring expressions.
When working with array destructuring expressions it's currently not possible to extend the values from the array being destructured with type declarations. As the destructured data often comes from various sources which may or may not be controlled by the scope executing the destructuring, a type declaration inside the expression allows stricter boundaries for the processed array:
$data = [42, 'Example', 2002]; [int $id, string $data, int $year] = $data;
This proposal adds a new syntax to add type declarations to array destructuring expressions. The type declarations behave identically to the type declarations processed for function calls (compare https://wiki.php.net/rfc/scalar_type_hints_v5). This includes a controllability of the behaviour using the strict_types directive. Type checks will be executed during the assignment of the variables when resolving the array destructuring expression. The variables will not keep any information concerning the check (they will not behave like typed variables afterwards, just like type checks in method signatures).
declare(strict_types=0); // as we have disabled strict_types this is ok [int $now, int $future] = ["2020", "2021"];
declare(strict_types=1); // as we have enabled strict_types this will lead to an error [int $now, int $future] = [2020, "2021"]; // Catchable fatal error: element 2 of array destructuring expression must be of type integer, string given
// assiciative array destructuring ["now" => int $now, "future" => int $future] = ["now" => 2020, "future" => 2021]; // nested array destructuring [ "2020s" => [ "now" => int $now, "future" => int $future, ] ] = [ "2020s" => [ "now" => 2020, "future" => 2021, ], "2030s" => [ "far away" => 2039, ], ]; // destructuring in a foreach loop $years = [["now", 2020], ["future", 2021]]; foreach ($years as [string $description, int $year]) { // ... }
Additionally to the examples above which all use scalar type declarations also object type declarations are possible:
foreach ($objectList as [DateTime $creationTime, MyObject $object]) { // ... }
The for PHP 8.0 accepted union types (https://wiki.php.net/rfc/union_types_v2) will also be allowed:
[int|float $number, string $description] = [1.5, "One point five"]
All of the examples above also work with the list() syntax.
Future scopes may include adding type checks to any assignment:
int $id = $data['id'];
Future scopes may include adding type declarations to foreach loops not utilizing array destructuring (https://externals.io/message/104485#104488):
$years = ["now" => 2020, "future" => 2021]; foreach ($years as string $description => int $year) { // ... }
None
Next PHP version (target 8.0)
None
None
Maybe, help needed
As this is a language change, a 2/3 majority is required. The vote is a straight Yes/No vote for accepting the RFC.
tbd
After the project is implemented, this section should contain
Keep this updated with features that were discussed on the mail lists.