What is unpacking?
For a long time, PHP has had the idea of argument unpacking built into it. With version 7.4, the language finally also got the provision of array unpacking — a very similar idea.
Array unpacking is, more or less, a shortcut for array_merge()
, a function used to merge two or more arrays together into a single array.
In PHP, array unpacking is done by the spread operator, denoted as ...
, also referred to as the splat operator in some other languages.
Syntactically, we could express unpacking as follows:
[...$array_1, ...$array_2, ...]
The ...
precede the array that we wish to unpack into the surrounding array.
Let's now consider an example of array unpacking.
Example of unpacking
Consider the following code:
<?php
$nums1 = [1, 5, 9];
$nums2 = [6, 0, -4];
We have two arrays, $nums1
and $nums2
, holding two separate collections of numbers and want to merge them into one single array for processing them all together.
This ain't a challenging task at all. We can either use array_merge()
or the power of array unpacking (which is essentially the same thing, albeit shorter to type and slightly faster to execute).
Here's how we can use array unpacking to consolidate both the arrays into one single array:
<?php
$nums1 = [1, 5, 9];
$nums2 = [6, 0, -4];
$nums = [...$nums1, ...$nums2];
Let's print $nums
to see what it contains:
<?php
$nums1 = [1, 5, 9];
$nums2 = [6, 0, -4];
$nums = [...$nums1, ...$nums2];
print_r($nums);
As expected, it contains numbers from both the arrays. Perfect!
Note how in $nums
we first have the elements of $nums1
and then the element of $nums2
. This is because we first unpacked $nums1
and then unpacked $nums2
.
If we switch the orders of these unpacking expressions, the content of $nums
would change as well:
<?php
$nums1 = [1, 5, 9];
$nums2 = [6, 0, -4];
$nums = [...$nums2, ...$nums1];
print_r($nums);
Also note that it's possible to unpack the same array more than once, as shown below:
<?php
$nums1 = [1, 5, 9];
$nums2 = [6, 0, -4];
$nums = [...$nums1, ...$nums1];
print_r($nums);
This works because, when unpacking, PHP simply iterates over the given array and copies each of its elements and appends it to the underlying array (where the unpacking is done).
Henceforth, it shouldn't (and even doesn't) matter if we unpack the same array more than once.
Unpacking associative arrays
When array unpacking was introduced in PHP 7.4, it didn't unfortunately work on associative arrays.
Trying to unpack an associative array threw an error, as shown below:
<?php // PHP 7.4
$point = ['x' => 10, 'y' => 20];
$point_3d = [...$point, 'z' => -10];
print_r($point_3d);
But after version 8.1, things changed. We're now able to unpack associative arrays as well.
Shown below is the same code above, run on PHP 8.1:
<?php // PHP 8.1
$point = ['x' => 10, 'y' => 20];
$point_3d = [...$point, 'z' => -10];
print_r($point_3d);
Just as desired, $point_3d
contains both the key-value pairs from $point
in addition to the 'z' => -10
pair.
In case a similar key is encountered at a later stage while unpacking a given array, it's used to override the previous value of that key in the main array. This can be seen as follows:
<?php
// PHP 8.1
$point = ['x' => 10, 'y' => 20];
$point_3d = [...$point, 'z' => -10, 'x' => 500];
print_r($point_3d);
$point
already contains a key x
in it and so when we unpack it, right at that point, the main array (where we unpack $point
) gets the key x
, with the value 10
. But then, by virtue of 'x' => 500
, this key gets replaced with the value 500
.
Things to note
Unpacking literal arrays is pointless
Although PHP supports the idea of unpacking literal arrays, there's really no point in doing so. Instead, we must directly inline the contents in the main array.
For example, consider the following:
<?php
$arr = [1, 2];
$arr2 = [...$arr, ...[3, 4]];
We are trying to create an array $arr2
based on the contents of $arr
, and then appending the numbers 3
and 4
to it.
The pointless thing in the code is ...[3, 4]
. Because we already know of the contents of the array [3, 4]
(i.e. it's fixed), there's absolutely no point of encapsulating them inside an array in the first place and then unpacking the array.
This code must be rewritten as follows:
<?php
$arr = [1, 2];
$arr2 = [...$arr, 3, 4];
The numbers 3
and 4
are specified directly within $arr2
; no unpacking involved.
Unpacking by-reference is not supported
We might be tempted to think that it's possible to unpack an array by-reference, i.e. make every element of the unpacked array an alias of the corresponding element in the main array.
However, this ain't possible! We can NOT unpack an array by-reference.
For example, the following PHP code, where we precede $arr
with &
(in the unpacking expression ...&$arr
) in hopes of unpacking it by-reference, is invalid:
<?php
$arr = [1, 2];
$arr2 = [...&$arr, 3, 4];
We can NOT precede an array in an unpacking expression with the &
symbol.