Type casting in array destructuring expressions View as Markdown

Declined
Authors
Enno Woortmann, enno.woortmann@web.de
Date
2020-03-25
Version
0.2
Target
PHP 8.0
Implementation
https://github.com/php/php-src/pull/5296
Source
wiki.php.net/rfc/typecast_array_desctructuring

Votes

Add type casting in array destructuring expressions closed
yes
6
no
26
32 voters
alcaeus no 2020-04-20 11:16
asgrim no 2020-04-13 16:41
ashnazg no 2020-04-15 13:32
brzuchal no 2020-04-12 18:37
bwoebi yes 2020-04-12 11:45
carusogabriel no 2020-04-09 12:16
colinodell no 2020-04-14 11:10
derick no 2020-04-09 10:29
duodraco no 2020-04-15 16:48
galvao no 2020-04-09 14:28
jasny yes 2020-04-22 23:52
jbnahan yes 2020-04-21 06:13
jhdxr no 2020-04-15 16:57
kalle no 2020-04-09 16:01
kguest no 2020-04-21 08:00
kocsismate yes 2020-04-16 11:08
levim no 2020-04-09 15:14
mariano no 2020-04-09 13:14
mike yes 2020-04-21 11:44
nicolasgrekas no 2020-04-09 10:13
nikic no 2020-04-09 10:11
ocramius no 2020-04-11 13:43
pollita no 2020-04-20 12:55
ramsey no 2020-04-09 16:37
rasmus no 2020-04-10 14:01
salathe no 2020-04-14 10:20
sergey no 2020-04-09 12:59
stas no 2020-04-22 18:50
svpernova09 no 2020-04-14 12:58
trowski no 2020-04-21 19:25
yunosh yes 2020-04-13 17:37
zimt no 2020-04-16 23:13
Choose one or more of the suggested future scopes in which you are interested closed
reference assignment casts
0
strict casts
16
nullable casts
19
type checks in array destructuring expressions
25
none
0
25 voters
ajf type checks in array destructuring expressions 2020-04-15 18:19
asgrim strict casts, nullable casts, type checks in array destructuring expressions 2020-04-13 16:41
bwoebi strict casts, nullable casts, type checks in array destructuring expressions 2020-04-12 11:46
carusogabriel strict casts, nullable casts, type checks in array destructuring expressions 2020-04-09 12:17
colinodell strict casts, nullable casts, type checks in array destructuring expressions 2020-04-14 11:10
duodraco strict casts, nullable casts, type checks in array destructuring expressions 2020-04-15 16:51
ekin strict casts, nullable casts, type checks in array destructuring expressions 2020-04-12 15:35
galvao type checks in array destructuring expressions 2020-04-09 14:30
jasny nullable casts, type checks in array destructuring expressions 2020-04-22 23:54
jbnahan strict casts, nullable casts, type checks in array destructuring expressions 2020-04-21 06:13
jhdxr type checks in array destructuring expressions 2020-04-15 16:58
kelunik nullable casts, type checks in array destructuring expressions 2020-04-19 20:24
kguest strict casts, nullable casts, type checks in array destructuring expressions 2020-04-21 08:01
kocsismate type checks in array destructuring expressions 2020-04-09 10:34
mariano strict casts, nullable casts, type checks in array destructuring expressions 2020-04-09 13:14
mike strict casts, type checks in array destructuring expressions 2020-04-21 11:45
nicolasgrekas nullable casts, type checks in array destructuring expressions 2020-04-09 10:15
nikic strict casts, nullable casts, type checks in array destructuring expressions 2020-04-09 10:12
ocramius strict casts, nullable casts, type checks in array destructuring expressions 2020-04-11 13:44
pollita strict casts, nullable casts, type checks in array destructuring expressions 2020-04-20 12:56
ramsey strict casts, nullable casts, type checks in array destructuring expressions 2020-04-09 16:37
seld type checks in array destructuring expressions 2020-04-09 11:48
sergey strict casts, nullable casts, type checks in array destructuring expressions 2020-04-09 12:59
svpernova09 strict casts, nullable casts, type checks in array destructuring expressions 2020-04-14 12:59
trowski nullable casts, type checks in array destructuring expressions 2020-04-21 19:26

Discussions on the mailing list

[RFC] [DISCUSSION] Type casting in array destructuring expressions
by Enno Woortmann · 12 messages
[VOTE] Type casting in array destructuring expressions
by Enno Woortmann · 2 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:52 UTC

Introduction

Adds the possibility to cast values while using array or list destructuring expressions.

Motivation

This proposal aims at type casts when working with data from a untyped source (eg. iterating over a CSV file, XML without a XSD defining the types of the elements). This data can often be handled in an elegant way using the existing capabilities of array destructuring. While simple variable assignments can be casted during the assignment this isn't possible during assignments via array destructuring. This proposal adds a new syntax for casting in array assignments. An example when handling a CSV file may look like:

1,Test,2002
2,Example,2010
3,Demo,2016
$handle = fopen('test.csv', 'r');
while (($data = fgetcsv($handle)) !== false) {
    [(int) $id, (string) $data, (int) $year] = $data;
    // ...
}

Proposal

While a simple variable assignment is able to execute a type cast this possibility isn't present for array or list destructuring expressions. Instead all values are assigned as they are:

// simple assignment with a cast
$now = (int) "2020";
// array destructuring without cast
[$now, $future] = ["2020", "2021"];

If the values stored in $a and $b after the array destructuring shall be casted each value must be casted manually afterwards:

[$now, $future] = ["2020", "2021"];
// either touch each value manually, use array_map or any other implementation approach to cast the values
$now = (int) $now;
$future = (int) $future;

This RFC proposes the possibility to cast the values inside the destructuring expression:

// destructuring and casting of a numeric array
[(int) $now, (int) $future] = ["2020", "2021"];
 
// destructuring and casting of an assiciative array
["now" => (int) $now, "future" => (int) $future] = ["now" => "2020", "future" => "2021"];
 
// destructuring and casting of a nested array
[
    "2020s" => [
        "now" => (int) $now,
        "future" => (int) $future
    ]
] = [
    "2020s" => [
        "now" => "2020",
        "future" => "2021"
    ],
    "2030s" => [
        "far away" => "2039"
    ]
];
 
// destructuring and casting in a foreach loop
$years = [["now", "2020"], ["future", "2021"]];
foreach ($years as [$description, (int) $year]) {
    // ...
}

While examples where all values should be casted to the identical type may be solved reasonably elegant with solutions like array_map it get's more difficult if the casts should cover various types:

// destructuring and casting with various types
["address" => (bool) $hasAddress, "floor" => (int) $floor] = ["address" => "My adress", "floor" => "3"];

All of the examples above also work with the list() syntax.

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

Implementation uses existing functions to compile the code. So existing Opcache implementations for assignments and castings are used.

Open Issues

Discussion

Regular type checks

During the discussion especially the idea of regular type checks instead of castings came up:

$years = ["2020", "2021"];
[int $now, int $future] = $years;

As a regular type check depends on the declare strict_types directive concerning the casting feature (strict_types=0 would result in an implicit cast similar to the proposed feature while strict_types=1 would result in a type error when the provided data doesn't match the type check) a regular type check covers different use cases than the proposed casting feature. (Also see future scopes)

Future Scope

Future scopes may include type casts during reference assignments which lead to a cast of the referenced variable (compare https://wiki.php.net/rfc/list_reference_assignment for reference assignments without casts):

// reference assignment cast
$now = "2020";
$now2 = (int) &$now;
 
// reference assignment cast combined with array destructuring
$years = ["2020", "2021"];
[(int) &$now, (int) &$future] = $years;

Future scopes may include strict type casts which avoid eg. (!int) “No Number String” to be casted to 0:

// strict assignment cast
$now = "2020";
$now2 = (!int) $now;
 
// strict assignment cast combined with array destructuring
$years = ["2020", "2021"];
[(!int) $now, (!int) $future] = $years;

Future scopes may include nullable type casts (compare https://externals.io/rfc/nullable-casting):

// nullable assignment cast
$now = "2020";
$now2 = (?int) $now;
 
// nullable assignment cast combined with array destructuring
$years = ["2020", "2021", null];
[(?int) $now, (?int) $future, (?int) $evenLater] = $years;

Future scopes may include regular type checks which depend on strict_types directive:

$years = ["2020", "2021"];
[int $now, int $future] = $years;

Proposed Voting Choices

Voting starts 2020-04-09 and ends 2020-04-23.

As this is a language change, a 2/3 majority is required. The vote is a straight Yes/No vote for accepting the RFC and merging the patch.

Vote: Add type casting in array destructuring expressions — yes: 6 · no: 26 (closed)


As the future scopes section of this proposal includes a lot of possible topics an additional poll to see which of these topics may be tackled in the near future:

Vote: Choose one or more of the suggested future scopes in which you are interested — reference assignment casts: 0 · strict casts: 16 · nullable casts: 19 · type checks in array destructuring expressions: 25 · none: 0 (closed)

Patches and Tests

The parser is already able to parse the syntax and requires no changes. The patch adds a change in the compile process in zend_compile_list_assign to be able to handle casting AST elements.

https://github.com/php/php-src/pull/5296

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

Links to external references, discussions or RFCs

Rejected Features

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