Powerful array destructuring in Laravel

Powerful array destructuring in Laravel that goes beyond the default PHP options.

Created on February 2021

Powerful array destructuring in Laravel

Array and object destructuring, if you have a JS background (especially ES6) is a great feature, enabling you to pick only specific keys of an object or to even get the remaining object.

An example of ES6 destructuring can be:

const post = {
  title: 'Article 1',
  slug: 'article-1',
  description: 'Lorem ipsum',
  tags: ['foo', 'bar'],
  gallery: [
    { image: 'image.jpg' },
    { image: 'image2.jpg' },
  ],
};

const { slug, tags, ...article } = post;

console.log(slug); // article-1
console.log(tags); // ['foo', 'bar']
console.log(article); // { title: 'Article 1', description: 'Lorem ipsum' ... } everything except slug and tags

That's really awesome, but unluckily in PHP things are different: variable assignment is a bit worse and we cannot use spread operator (the three dots) to get the rest of our array. You can check an example of current PHP array destructuring in this great article on Stitcher.io.

Laravel enhancement

With Laravel we have every needed method in the Illuminate\Support\Arr class to achieve a better destructuring than ES6, if you don't believe me, check the following example:

$post = [
	'title' => 'Article 1',
	'slug' => 'article-1',
	'description' => 'Lorem ipsum',
	'tags' => ['foo', 'bar'],
	'gallery' => [
	    ['image' => 'image.jpg'],
	    ['image' => 'image2.jpg'],
	],
];

[$tags, $gallery, $article] = Arr::destructure($post, ['tags', 'gallery']);

dump($tags); // ['foo', 'bar']
dump($gallery); // [['image' => 'image.jpg'], ['image' => 'image2.jpg']]
dump($article) // ['title' => 'Article 1', 'slug' => 'article-1', 'description' => 'Lorem ipsum']

You can even create group of keys to get a subset array:

[$slug, $meta, $article] = Arr::destructure($post, ['slug', ['tags', 'gallery']]);

dump($slug); // 'article-1'
dump($meta); // ['tags' => ['foo', 'bar'], 'gallery' => [['image' => 'image.jpg'], ['image' => 'image2.jpg']]]
dump($article); // ['title' => 'Article 1', 'description' => 'Lorem ipsum']

Pretty neat, doesn't it? But what's that Arr::destructure()? That's our new helper that integrates within the Laravel Arr class through a macro.

How does it work

If you're just interested in the package and you want to skip the explanation, I've published the code as laravel package on GitHub: Laravel Array Destructuring.

The code behind it is very simple, let's take a look and analyze it line-per-line:

function destructure (array $array, $keys): array {
    $keys = Arr::wrap($keys);
    $results = [];

    foreach ($keys as $key) {
        if (is_array($key)) {
            $results[] = Arr::only($array, $key);
        } else {
            $results[] = array_key_exists($key, $array) ? $array[$key] : null;
        }
    }

    $results[] = Arr::except($array, Arr::flatten($keys));

    return $results;
}
  1. At the beginning, we're wrapping $keys with the helper Arr::wrap. It works like this: if the given input is an array, just return it, otherwise return an array with that value inside it.
  2. Then we loop over the keys and we have a condition: if the key is an array, namely what we call a group of keys, we apply the Arr::only helper to append only the subset of those keys from the initial array; otherwise, we get the specific value or null if the key does not exist.
  3. At the end, we append the remaining array to the results. To achieve it we're doing two things: 1.1. We flatten the array of keys, so every "group of keys" won't exist anymore and we retrieve a plain list. For example Arr::flatten(['foo', ['bar', 'baz']]) will return ['foo', 'bar', 'baz']. 1.2. Then we remove the given flatten keys (the keys to "destructure") from the initial array to append it "cleaned".

As I said it's pretty simple how it works and remember that you can install it just running composer require danilopolani/laravel-array-destructuring inside your project. You can find more info about it on the package GitHub repository.

Next

Run a one-off command on Twitch IRC with TMI.php

Previous

Setup a Valheim private server on a VPS in less than 5 minutes