# RFC: Type declarations in array destructuring expressions

- Status: Inactive
- Authors: Enno Woortmann, enno.woortmann@web.de
- Date: 2020-04-16
- Version: 0.1
- Target: PHP 8.0
- Original: https://wiki.php.net/rfc/typehint_array_desctructuring
- Page: https://externals.io/rfc/typehint_array_desctructuring
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Discussions on the mailing list

- [\[RFC\] Cast in foreach](https://externals.io/message/104485.md) — started on 2019-02-21, 6 messages
- [Type hints in array destructuring expressions](https://externals.io/message/109676.md) — started on 2020-04-16, 9 messages

---

## 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:

```php
$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](https://externals.io/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).

```php
declare(strict_types=0);
 
// as we have disabled strict_types this is ok
[int $now, int $future] = ["2020", "2021"];
```

```php
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
```

```php
// 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:

```php
foreach ($objectList as [DateTime $creationTime, MyObject $object]) {
    // ...
}
```

The for PHP 8.0 accepted union types ([https://wiki.php.net/rfc/union\_types\_v2](https://externals.io/rfc/union_types_v2)) will also be allowed:

```php
[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:

```php
int $id = $data['id'];
```

---

Future scopes may include adding type declarations to foreach loops not utilizing array destructuring (<https://externals.io/message/104485#104488>):

```php
$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

[https://wiki.php.net/rfc/typecast\_array\_desctructuring](https://externals.io/rfc/typecast_array_desctructuring)

## Rejected Features

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