Array destructuring in PHP

In my day to day job I write in a number of programming languages. The majority of my time is spent writing PHP but I very much enjoy writing other languages, such as Go and Javascript, too!

One of the things I like the most about JavaScript, and PHP also to some extent, is how flexible and expressive they CAN be (but not always are). I also believe that JavaScript, PHP, and Python have a number of features that make them a good fit for serving the forefront of the web. Most of those features have to do with loose and dynamic typing. Personally I like how freely you can transform data without worrying too much about the structure.

The most versatile type of PHP, to me, is the array. The array can be used to act like many different classic data types. You can use them as a List, a Set (although that requires some specific handling), a HashMap, just to name a few.

PHP 7.1 array super-powers!

In PHP 7.1 the array type has become even more powerful! An RFC was accepted (and implemented) to provide square bracket syntax for array destructuring assignment.

This change to the language made it possible to extract values from array more easily. For example, consider the following options array:

<?php

$options = ['enabled' => true, 'compression' => 'gzip'];

If we'd want to assign the options to variables we could use something like this:

$enabled = $options['enabled'];
$compression = $options['compression'];

This is not so bad, but using the features of this new RFC we could have a slightly more expressive way to define this. You might know this kind of expression if you've used ES6's form of this.

let options = {enabled: true, compression: 'gzip'};  
let { enabled, compression } = options;  

In this example the enabled and compression key are extracted into variables in a language contract that can be viewed as the inverse of the initial options assignment. In this example the variable names are implicit. In the full form the example is a little more verbose.

let { enabled: enabled, compression: compression } = options;  

The expansion also allows for renamed and can be mixed with the shorter version:

let { enabled, compression: algorithm } = options;  

Since version 7.1 we can use these same type of syntax in PHP too!

$options = ['enabled' => true, 'compression' => 'gzip'];
['enabled' => $enabled, 'compression' => $compression] = $options;

In this example the value of the enabled key is assigned to the $enabled variable and the same goes for the compression key.


List assignments

Apart from associative array destructuring, list destructuring is also possible. This type of destructuring is particularly useful for when you're using arrays as you would a Tuple. A tuple is a finite ordered list that holds a fixed number of items.

[$a, $b] = [1, 2];
// $a is now 1
// and $b is 2

It also works when you're using variables in the source array, so you can effectively swap variables using this syntax:

$a = 1;
$b = 2;
[$a, $b] = [$b, $a];

// $a is now 2
// and $b is 1

Nested destructuring

In many PHP application the application is responsible for retrieving a large set of nested data. In this case the nested form of array destructuring can come in handy.

$options = ['enabled' => true, 'compression' => ['algo' => 'gzip']];
[
    'enabled' => $enabled,
    'compression' => [
        'algo' => $compressionAlgo
    ]
] = $options;
// $enabled is TRUE
// $compressionAlgo is "gzip"

This nested form can also be combined with the list destructuring, so you can go as wild as you feel like it.

$x = ['o' => [1, 2, 3]];
['o' => [$a, $b, $c]] = $x;

Or if you really want to loose your mind, consider this example:

$x = ['o' => [[1, 2, 3], ['what' => 'WHAT']]];
['o' => [[$one, $two, $three], ['what' => $what]]] = $x;

I hope you have fun exploring the new possibilities using these techniques!

Frank de Jonge

Frank de Jonge is a freelance developer from Amsterdam, a founding member of The PHP League, and an occasional speaker.

Amsterdam, The Netherlands http://frankdejonge.nl

Subscribe to Frank de Jonge's Blog

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!