DEV Community

Cover image for How to Append Arrays in PHP: + vs. array_merge
David
David

Posted on • Originally published at bluecollardev.io

How to Append Arrays in PHP: + vs. array_merge

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_merge function. 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:

$left + $right array_merge($left, $right)
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

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.

👉 The + operator is more intuitive for arrays with explicit keys.

Option 2: The array_merge Function

The built-in function array_merge is similar, but a bit more intricate. Again, array_merge($a, $b) appends $b to $a.

  • 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'];
Enter fullscreen mode Exit fullscreen mode
  • ⚠ī¸ Because the implicit keys match, the + operator only uses the values from the left-hand side.

  • array_merge appends values for numeric keys: we get what we expect from an "append" function.

👉 To append two "normal" arrays, use array_merge.

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']
Enter fullscreen mode Exit fullscreen mode
  • The + operator's result is consistent with what we learned previously. When a key matches, the value from $a has priority.

  • At a first glance, the result of array_merge looks similar like before, but notice that the keys changed. array_merge actually 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 + and 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'];
Enter fullscreen mode Exit fullscreen mode
  • The + operator handles string keys the same way, it handled numeric keys: when a key matches, the value from $a is taken.

  • Now, array_merge behaves differently: when a string key matches, the value from $b is taken.

ℹī¸ 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
];
Enter fullscreen mode Exit fullscreen mode

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 TypeError when passing null to the + operator or array_merge.
  • PHP 7.4 also produces a fatal error, when using null as an operand on the + operator. But when using null as an argument in array_merge, PHP 7.4 only produces a warning and returns null.

In my opinion, generating a type error or warning is not acceptable. I strongly suggest you never use the + operator or array_merge on null values.

⚡ Ensure that none of the arrays are null.

Top comments (2)

Collapse
 
bdelespierre profile image
Benjamin Delespierre

have you tried this?

[1,2,3,...[4,5]] == range(1,5)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
davidrjenni profile image
David

Thanks for your feedback. 🙏 You are absolutely right. The spread operator is a more readable alternative for array_merge, if you are working with array literals.

⚠ī¸ In all current PHP versions (up to 8.0) the spread operator does not work for arrays with string keys.

But that will change in PHP 8.1 . 🎉🎉🎉

Then it's effectively an array_merge alternative for array literals.