DEV Community

Roy R.
Roy R.

Posted on • Edited on

Destructuring in php?

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:

const {a, b, c, ...rest} = {a:'Apple', b:'Banana', c:'Cantalope', d:'Durian'}
Enter fullscreen mode Exit fullscreen mode

...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

// 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
}
Enter fullscreen mode Exit fullscreen mode

another approach using the optional chaining operator from typescript:

const username = api?.data?.user?.name || 'Unknown user'
Enter fullscreen mode Exit fullscreen mode

But here's another option, using destructuring:

const { data={} } = api
const { user={} } = data
const { name='Unknown' } = user
console.log(name) // Unknown

Enter fullscreen mode Exit fullscreen mode

Destructuring in php

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

[$a, $b, $c] = ['apple', 'banana', 'cantaloupe'];
Enter fullscreen mode Exit fullscreen mode

OR

[,,,$d,$e] = ['apple', 'banana', 'cantaloupe', 'durian', 'eggplant'];
Enter fullscreen mode Exit fullscreen mode

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

$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
Enter fullscreen mode Exit fullscreen mode

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.

$api = {
  data: {
    user: {
      name: 'George Washington'
  }
}; // A nested data object
Enter fullscreen mode Exit fullscreen mode

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:

$fruit = ['apple', 'banana', 'canteloupe', 'durian'];
[$a, ...$rest] = $fruit;
var_dump($rest); // ['banana', 'canteloupe', 'durian']
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (2)

Collapse
 
cvladan profile image
cvladan

I don't think [$a, ...$rest] = $fruit; works.

Actually, I'm pretty sure it doesn't work, as I've just spent ages applying latest PHP versions and no – it doesn't work, at least for me.

Collapse
 
robrecord profile image
Record

Thanks Roy! This was helpful.