PHP RFC: Type declarations in array destructuring expressions
- Version: 0.1
- Date: 2020-04-16
- Target Version: PHP 8.0
- Author: Enno Woortmann, enno.woortmann@web.de
- Status: Draft
Introduction
Adds the possibility to extend values with type declarations while using array or list destructuring expressions.
Motivation
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;
Proposal
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 scope
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) { // ... }
Backward Incompatible Changes
None
Proposed PHP Version(s)
Next PHP version (target 8.0)
RFC Impact
To SAPIs
None
To Existing Extensions
None
To Opcache
Maybe, help needed
Open Issues
Proposed Voting Choices
As this is a language change, a 2/3 majority is required. The vote is a straight Yes/No vote for accepting the RFC.
Patches and Tests
tbd
Implementation
After the project is implemented, this section should contain
- the version(s) it was merged into
- a link to the git commit(s)
- a link to the PHP manual entry for the feature
- a link to the language specification section (if any)
References
Rejected Features
Keep this updated with features that were discussed on the mail lists.