rfc:typehint_array_desctructuring

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

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature
  4. a link to the language specification section (if any)

References

Rejected Features

Keep this updated with features that were discussed on the mail lists.

rfc/typehint_array_desctructuring.txt · Last modified: 2020/04/16 13:56 by wol-soft