How to Append Arrays in PHP

How to Append Arrays in PHP

The + Operator vs. array_merge

ยท

5 min read

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 + $rightarray_merge($left, $right)
Key types matterNoYes
If numeric key matchesLeft-hand value is usedAppended
If string key matchesLeft-hand value is usedRight-hand value is used
Renumbers result keysNoYes

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'];
  • โš ๏ธ 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']
  • 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'];
  • 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
];

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.

ย