Destructuring in php?
Tags: php, destructuring, spread, splat
Published: 2021-10-31 17:14:36

I work on javascript/typescript on a constant basis, and php on an infrequent basis (on my legacy php app http://www.ninjawars.net).

When I switch back to php after a long time of using javascript or typescript, I really miss the clean code that you can write by using destructuring.

Now, I talked a bit in another post about short circuit evaluation in js vs php as a way to make code terser and with much less boilerplate, but what about destructuring in php?

## Destructuring in js

First, let's glance at destructuring in js:

```js
const {a, b, c, ...rest} = {a:'Apple', b:'Banana', c:'Cantalope', d:'Durian'}
```

...not only is destructuring smooth, it also allows for the powerful `...rest` spread syntax.  I can't tell you the number of times that I have had some complex code block in javascript that was simplified by converting it to use destructuring, or perhaps avoiding an undefined property that destructuring handles smoothly, like:
`property api.data.user.name may be undefined`

```js
// The dreaded chain of && to avoid undefined properties
if(api && api.data && api.data.user && api.data.user.name){
 const username = api.data.user.name || 'unknown' // finally do something
}
```

another approach using the optional chaining operator from typescript:
```js
const username = api?.data?.user?.name || 'Unknown user'
```

But here's another option, using destructuring:
```js
const { data={} } = api
const { user={} } = data
const { name='Unknown' } = user
console.log(name) // Unknown

```

## Destructuring in php

Sadly, php only supports a very limited bit of destructuring, specifically, when destructuring arrays, by using `list()` destructuring or `[]` destructuring.

```php
[$a, $b, $c] = ['apple', 'banana', 'cantaloupe'];
```

OR

```php
[,,,$d,$e] = ['apple', 'banana', 'cantaloupe', 'durian', 'eggplant'];
```

Thankfully, you are also allowed to destructure named keys from associative arrays:

```php
$fruit = [
 'a'=>'apple',
 'b'=>'banana',
 'c'=>'cantaloupe', 
 'd'=>'durian',
 'e'=>'eggplant'
];
// Have to set the $fruit var because for some reason php doesn't like it when you try to directly destructure from the  associative array you just created.
['d'=>$d, 'e'=>e] = $fruit;
echo $d; // Durian now
echo $e; // Eggplant
```

So *as long as you are dealing with an array or an associative array* you can do some destructuring.

## Destructuring php objects

It's somewhat possible to destructure a php object by transforming it into an array.

```php
$api = {
  data: {
    user: {
      name: 'George Washington'
  }
}; // A nested data object
```
To destructure this you generally have to turn it into an array first, and deal with the proposition of turning it's nested properties into arrays as well.  This may be a diminishing return on effort.

### What about ...spreading values?

More modern versions of php, at least 8+, support spread/splat operators on arrays in weird ways, having supported spread operators on function arguments since way back in php 5.6.

Spread on arrays in php:

```php
$fruit = ['apple', 'banana', 'canteloupe', 'durian'];
[$a, ...$rest] = $fruit;
var_dump($rest); // ['banana', 'canteloupe', 'durian']
```
For whatever reason, you have to assign to a variable before you can then destructure that variable.  Immediately destructuring a variable that you are just assigning causes a php error that says:
`PHP Fatal error:  Spread operator is not supported in assignments in php shell code on line 1`

So the spread operator exists, and it works, you just can't use destructuring immediately upon assignment in php.

## The takeaway

Still, there is a lot of potential for destructuring as a way to clean up and simplify code.