Arrays7 min readExamples run on PHP 8.5.10

array_merge()

Learn how array_merge() joins arrays, overwrites string keys, renumbers integer keys and differs from the + operator, with three runnable PHP 8.4 examples.

Signature

array_merge(array ...$arrays): array

Purpose

array_merge() builds a new array by placing the elements of several arrays one after another. It is the usual tool for combining lists, or for layering a set of option overrides on top of defaults. The input arrays are not modified; you receive a fresh array.

The two rules to remember are about keys:

  • A string key that appears in more than one array keeps only the value from the last array that has it.
  • An integer key never overwrites anything. The value is appended, and all integer keys in the result are renumbered from 0.

PHP 8.4 signature

Parameters and defaults

...$arrays is a variadic list of zero or more arrays. There are no other parameters and no default values. Arguments are processed left to right, so the order you pass them in decides which string-keyed value wins.

Return value and failure cases

The function returns the merged array. Calling it with no arguments returns an empty array. Passing something that is not an array, such as null or a string, throws a TypeError, so convert or check values first. Because the result is a new array, you must assign or use the return value; calling array_merge($a, $b); on its own changes nothing.

Example 1: defaults and overrides

With string keys, the later array wins. This makes merging a good fit for configuration where the caller supplies only the values that differ from the defaults.

Example
<?php
$defaults = ['color' => 'red', 'size' => 'M'];
$custom = ['size' => 'L', 'material' => 'cotton'];
echo json_encode(array_merge($defaults, $custom), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"color":"red","size":"L","material":"cotton"}

The size value from $custom replaces the default, color stays, and material is added at the end.

Example 2: renumbering versus the + operator

Integer keys are renumbered by array_merge(), so the original numbers are lost. The + array union operator behaves differently: it keeps the keys of the left array and only adds keys that are missing from it.

Example
<?php
$a = [5 => 'a', 9 => 'b'];
$b = [5 => 'c', 'x' => 'd'];
echo json_encode(array_merge($a, $b)), "\n";
echo json_encode($a + $b), "\n";
Output
{"0":"a","1":"b","2":"c","x":"d"}
{"5":"a","9":"b","x":"d"}

The merge produces keys 0, 1, 2 and x, and both 'a' and 'c' survive. The union keeps key 5 from $a, so 'c' is discarded. Pick the operator when integer keys carry meaning, such as IDs, and array_merge() when you simply want to concatenate lists.

Example 3: merging many arrays and no arguments

Because the parameter is variadic, you can unpack an array of arrays with the spread operator. Empty arrays contribute nothing.

Example
<?php
$groups = [[1, 2], [3], [], [4, 5]];
$merged = array_merge(...$groups);
echo json_encode($merged), "\n";
echo json_encode(array_merge()), "\n";
Output
[1,2,3,4,5]
[]

This flattens one level of nesting into a single list. The final call with no arguments returns [].

Edge cases

  • Single argument: array_merge($list) still renumbers integer keys, so it can be used to reindex an array that has gaps.
  • Numeric strings as keys: a key like '7' is stored by PHP as the integer 7, so it is renumbered like any other integer key.
  • Shallow merge: only the top level is combined. If two arrays hold a nested array under the same string key, the later nested array replaces the earlier one entirely. For recursive combination, look at array_merge_recursive() or array_replace_recursive().
  • Empty input arrays: an empty array simply adds no elements.
  • Argument order: array_merge($a, $b) and array_merge($b, $a) produce different element order and may produce different values for shared string keys.

Common mistakes

  1. Expecting integer keys to be preserved. If you merge arrays indexed by user ID, the IDs disappear. Use + or array_replace() in that situation.
  2. Ignoring the return value. The original array is left unchanged, so you must store the result.
  3. Passing null. An optional value that may be null should be defaulted, for example with $value ?? [], before merging.
  4. Assuming deep merging. Nested settings are replaced, not combined.
  5. Mixing up overwrite direction. For string keys the last array wins with array_merge(), but the first array wins with +.
  • array_merge_recursive() merges nested arrays and collects values that share a string key.
  • array_replace() replaces by key, including integer keys, without renumbering.
  • array_combine() builds an array from one array of keys and one of values.
  • The + array union operator keeps the left array's keys and fills in missing ones.

Recap

array_merge() appends arrays in order and returns a new array. Later string keys overwrite earlier ones, integer keys are renumbered from zero, no arguments yields an empty array, and every argument must be an array. Use it for lists and option overrides, and choose + or array_replace() when integer keys must survive.

Tested examples

Merging defaults with overrides
<?php
$defaults = ['color' => 'red', 'size' => 'M'];
$custom = ['size' => 'L', 'material' => 'cotton'];
echo json_encode(array_merge($defaults, $custom), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"color":"red","size":"L","material":"cotton"}
Renumbering versus the + operator
<?php
$a = [5 => 'a', 9 => 'b'];
$b = [5 => 'c', 'x' => 'd'];
echo json_encode(array_merge($a, $b)), "\n";
echo json_encode($a + $b), "\n";
Output
{"0":"a","1":"b","2":"c","x":"d"}
{"5":"a","9":"b","x":"d"}
Spreading many arrays and calling with no arguments
<?php
$groups = [[1, 2], [3], [], [4, 5]];
$merged = array_merge(...$groups);
echo json_encode($merged), "\n";
echo json_encode(array_merge()), "\n";
Output
[1,2,3,4,5]
[]