array_merge($a, $b) returns a new array with the elements of $a followed by the elements of $b. Numeric keys are renumbered from 0; when both arrays have the same string key, the value from the later array wins. Pass as many arrays as you like.
array_merge() does not change its arguments. It returns the combined array, so assign the result: $all = array_merge($all, $more);.
Numeric keys are renumbered
array_merge() treats integer keys as positions, not as names. Every element with an integer key is appended and gets a fresh key from 0, even if the arrays used the same numbers or gaps. That is what you want for lists, and a surprise when the numbers are IDs.
String keys that look like integers ('101') are stored as integers, so they are renumbered too. Keys like 'id101' stay as they are.
array_merge vs the + operator
The + operator (array union) also combines arrays, but with the opposite rule: for any key that already exists in the left array, the left value wins and the right one is dropped. It never renumbers. This makes + the natural way to fill in defaults, and array_merge() the natural way to override them.
array_merge($a, $b) | $a + $b | |
|---|---|---|
| Same string key | value from $b | value from $a |
| Integer keys | renumbered, all values kept | kept, $b loses clashes |
| Typical use | joining lists, overriding settings | filling in defaults, keeping IDs |
The last example in the block is the classic + trap: ['a', 'b'] + ['x', 'y', 'z'] gives a, b, z, because keys 0 and 1 already exist on the left.
Spread syntax: [...b]
The spread operator unpacks arrays inside an array literal. It behaves like array_merge(): integer keys are renumbered and, since PHP 8.1, string keys are allowed and the later one wins. It reads well when you mix arrays with single values.
To append an array to an existing one in place, see array_push() with the spread operator.
Merge an array of arrays
When the arrays to combine are themselves in a list, spread that list into array_merge(). This is also the fast way to merge inside a loop: collect the pieces, then merge once.
Writing $all = array_merge($all, $batch); inside the loop works, but it copies the whole growing array on every pass, which gets slow with thousands of items.
array_merge_recursive and array_replace
array_merge_recursive() merges nested arrays too, but for a duplicate string key holding plain values it does not overwrite: it collects both values into a new array. That is rarely what you want for configuration. array_replace_recursive() is usually the right tool there: it overwrites values at every level and keeps keys.
Read the three JSON lines from top to bottom: array_merge() replaced the whole db array and lost host, array_merge_recursive() turned port and debug into two-element lists, and array_replace_recursive() produced the config you meant.
Common mistake: merging removes nothing
array_merge() keeps duplicate values that sit under different keys. Merging two lists of tags gives you each shared tag twice. Pass the result through array_unique() and then array_values() to renumber it.
The array_unique page covers removing duplicates from rows and nested arrays.
Frequently Asked Questions
What is the difference between array_merge and + in PHP?
For duplicate string keys, array_merge($a, $b) keeps the value from $b, while $a + $b keeps the value from $a. For numeric keys, array_merge() appends and renumbers everything, while + keeps the numeric keys and drops any element of $b whose key already exists in $a.
How do I merge arrays and keep the numeric keys?
Use $a + $b if the left array should win, or array_replace($a, $b) if the right array should win. array_merge() always renumbers numeric keys from 0.
How do I merge an array of arrays in PHP?
Spread the outer array into array_merge(): $all = array_merge(...$lists);. It returns [] for an empty list. Collect the arrays in a loop first and merge once at the end; calling array_merge() inside the loop copies the growing result every time.
Can I use the spread operator with string keys in PHP?
Yes, since PHP 8.1. [...$a, ...$b] then behaves like array_merge($a, $b): numeric keys are renumbered and a later string key overwrites an earlier one.