Appending or merging is a common array operation. And since arrays are used everywhere in PHP, you cannot afford not to know how to do it properly. But why would it be so hard?
There are two options to append or merge arrays in PHP: the
+operator and the
array_mergefunction. It's not always clear, which one to use.
Arrays in PHP are actually ordered maps. We use and think about them as normal arrays and associative arrays. But since the underlying structure is the same, some results might surprise you.
The differences are subtle and I often forget them. This is why created this post.
TL;DR, here are the key takeaways as a cheat sheet:
|Key types matter||No||Yes|
|If numeric key matches||Left-hand value is used||Appended|
|If string key matches||Left-hand value is used||Right-hand value is used|
|Renumbers result keys||No||Yes|
But for those of you who are interested in the details, let's dive right into it.
Option 1: The
+ operator, applied to arrays is also called the union operator. When computing
$a + $b,
$b is appended to
$a. But if a key occurs in both arrays, only the value from the left-hand side is used.
The type of the keys is ignored: numeric and string keys are treated the same way and the keys are always preserved.
+ operator is more intuitive for arrays with explicit keys.
Option 2: The
The built-in function
array_merge is similar, but a bit more intricate. Again,
array_merge($a, $b) appends
If a string key occurs in both arrays, the value from the right-hand side is used.
But if a numeric key matches, the corresponding value from the right-hand side is appended. Because this behavior cannot preserve the keys, the resulting numeric keys are renumbered.
👉 As we'll see, this makes
array_merge more geared towards handling "normal" arrays.
Use Case 1: Normal Arrays
What are "normal" arrays in PHP? They are arrays with numeric keys, starting at zero:
['x1', 'y1'] is a shortcut for
[0 => 'x1', 1 => 'y2'].
Let's see how the
+ operator and
array_merge perform on "normal" arrays:
$a = ['x1', 'y1']; // == [0 => 'x1', 1 => 'y1'] $b = ['y2', 'z2']; // == [0 => 'y2', 1 => 'z2'] $a + $b == ['x1', 'y1']; // == [0 => 'x1', 1 => 'y1'] array_merge($a, $b) == ['x1', 'y1', 'y2', 'z2'];
⚠️ Because the implicit keys match, the
+operator only uses the values from the left-hand side.
array_mergeappends values for numeric keys: we get what we expect from an "append" function.
👉 To append two "normal" arrays, use
Use Case 2: Numeric Keys
But what happens if we use numeric keys, which do not start at zero?
$a = [1 => 'x1', 2 => 'y1']; $b = [2 => 'y2', 3 => 'z2']; $a + $b == [1 => 'x1', 2 => 'y1', 3 => 'z2']; array_merge($a, $b) == ['x1', 'y1', 'y2', 'z2']; // == [0 => 'x1', 1 => 'y1', 2 => 'y2', 3 => 'z2']
+operator's result is consistent with what we learned previously. When a key matches, the value from
At a first glance, the result of
array_mergelooks similar like before, but notice that the keys changed.
array_mergeactually renumbers the numeric keys, starting at zero.
⚠️ If you need to preserve numeric keys,
array_merge will not work.
Use Case 3: String Keys
Let's move on and see how
array_merge handle arrays with string keys.
$a = ['a' => 'x1', 'b' => 'y1']; $b = ['b' => 'y2', 'c' => 'z2']; $a + $b == ['a' => 'x1', 'b' => 'y1', 'c' => 'z2']; array_merge($a, $b) == ['a' => 'x1', 'b' => 'y2', 'c' => 'z2'];
+operator handles string keys the same way, it handled numeric keys: when a key matches, the value from
array_mergebehaves differently: when a string key matches, the value from
ℹ️ For matching string keys,
+ takes the value from the left-hand side,
array_merge takes the value from the right-hand side.
Use Case 4: Mixed Key Types
Arrays with mixed key types do not change anything about the rules explained above. The merging procedure applies the rules key by key. Here you can see all the rules in action:
$a = ['a' => 'x1', 'b' => 'y1', 'z1', 5 => '1st']; $b = ['b' => 'x2', 'c' => 'y2', 'z2', 5 => '2nd']; $a+$b == [ 'a' => 'x1', // key only in $a 'b' => 'y1', // matching string key -> value from $a 0 => 'z1', // matching implicit numeric key -> value from $a 5 => '1st', // matching numeric key -> value from $a 'c' => 'y2', // key only in $b ]; array_merge($a, $b) == [ 'a' => 'x1', // key only in $a 'b' => 'x2', // matching string key -> value from $b 0 => 'z1', // numeric key -> append and renumber 1 => '1st', // numeric key -> append and renumber 'c' => 'y2', // key only in $b 2 => 'z2', // numeric key -> append and renumber 3 => '2nd', // numeric key -> append and renumber ];
Edge Case: Null Values
Finally, let's see what happens when one of the arrays is
null. It depends on the PHP version:
- PHP 8.0 throws a
- PHP 7.4 also produces a fatal error, when using
nullas an operand on the
+operator. But when using
nullas an argument in
array_merge, PHP 7.4 only produces a warning and returns
In my opinion, generating a type error or warning is not acceptable. I strongly suggest you never use the
+ operator or
⚡ Ensure that none of the arrays are