Merge Arrays

La Lakshmi Priya Updated 19 Oct 2026
6 min read ·Lesson 134 of 143

Merging combines two or more arrays into one. Typical tasks include joining lists, applying user settings on top of defaults, layering configuration files, and pairing keys with values. PHP offers several ways to merge, and they handle duplicate keys differently — choosing the wrong one is a common source of bugs.

TechniqueInteger KeysDuplicate String KeysNested Arrays
array_merge($a, $b)RenumberedLater value winsReplaced as a whole
[...$a, ...$b]RenumberedLater value wins (PHP 8.1+)Replaced as a whole
$a + $bKeptFirst value winsReplaced as a whole
array_replace($a, $b)KeptLater value winsReplaced as a whole
array_replace_recursive($a, $b)KeptLater value winsMerged level by level
array_merge_recursive($a, $b)RenumberedValues combined into arraysMerged level by level
array_combine($keys, $values)——Builds a new array from two lists

array_merge()

Lists

<?php
$morning = ['Yoga', 'Breakfast'];
$evening = ['Walk', 'Dinner'];

$day = array_merge($morning, $evening);

print_r($day);

Output

Array
(
    [0] => Yoga
    [1] => Breakfast
    [2] => Walk
    [3] => Dinner
)

All elements are combined, and integer keys are renumbered from 0.

Associative Arrays

<?php
$defaults = ['theme' => 'light', 'language' => 'en', 'perPage' => 20];
$userSettings = ['language' => 'ta', 'perPage' => 50];

print_r(array_merge($defaults, $userSettings));

Output

Array
(
    [theme] => light
    [language] => ta
    [perPage] => 50
)

When the same string key exists in both arrays, the value from the later array wins. This makes array_merge($defaults, $overrides) a natural way to apply settings.

Integer Keys Are Renumbered — Even Meaningful Ones

<?php
$productsById = [101 => 'Gel Pen', 205 => 'Notebook'];
$moreProducts = [310 => 'Desk Lamp'];

print_r(array_merge($productsById, $moreProducts));

Output

Array
(
    [0] => Gel Pen
    [1] => Notebook
    [2] => Desk Lamp
)

The product IDs are lost. When integer keys carry meaning (IDs, years, codes), use + or array_replace() instead.

Merging Many Arrays at Once

<?php
$pages = [[1, 2, 3], [4, 5], [6]];

$allItems = array_merge(...$pages);

echo implode(', ', $allItems) . "\n";
var_dump(array_merge(...[]));

Output

1, 2, 3, 4, 5, 6
array(0) {
}

array_merge(...$pages) unpacks the list of arrays as separate arguments, merging them in one call. Since PHP 7.4, array_merge() with no arguments returns an empty array, so this is safe even when $pages is empty.

Performance tip: Calling $result = array_merge($result, $page) inside a loop copies the growing result on every iteration, which becomes slow for large data. Collect the pieces in an array and merge once with array_merge(...$pieces).


The Union Operator +

<?php
$defaults = ['theme' => 'light', 'language' => 'en', 'perPage' => 20];
$userSettings = ['language' => 'ta', 'perPage' => 50];

print_r($userSettings + $defaults);

$productsById = [101 => 'Gel Pen', 205 => 'Notebook'];
$moreProducts = [310 => 'Desk Lamp', 101 => 'Blue Pen'];

print_r($productsById + $moreProducts);

Output

Array
(
    [language] => ta
    [perPage] => 50
    [theme] => light
)
Array
(
    [101] => Gel Pen
    [205] => Notebook
    [310] => Desk Lamp
)
  • + keeps all keys from the left array and adds keys from the right array only if they are missing.
  • The left value wins for duplicates, so $overrides + $defaults fills in missing settings.
  • Integer keys are preserved: product 101 keeps the name from the left array, and 310 is added.

Remember that + is not a way to append lists: ['A', 'B'] + ['C', 'D', 'E'] gives ['A', 'B', 'E'].


array_replace() and array_replace_recursive()

array_replace() works like array_merge() for string keys, but preserves integer keys:

<?php
$stockById = [101 => 50, 205 => 12];
$stockUpdate = [205 => 30, 310 => 8];

print_r(array_replace($stockById, $stockUpdate));

Output

Array
(
    [101] => 50
    [205] => 30
    [310] => 8
)

Product 205 is updated, 310 is added, and all IDs remain intact.

Merging Nested Configuration

With nested arrays, array_replace() (like array_merge()) replaces each top-level entry as a whole. array_replace_recursive() merges level by level instead:

<?php
$defaults = ['db' => ['host' => 'localhost', 'port' => 3306]];
$override = ['db' => ['host' => 'db.prod']];

echo json_encode(array_replace($defaults, $override)) . "\n";
echo json_encode(array_replace_recursive($defaults, $override)) . "\n";

Output

{"db":{"host":"db.prod"}}
{"db":{"host":"db.prod","port":3306}}
  • array_replace() replaced the entire db section, losing the port.
  • array_replace_recursive() replaced only db.host and kept db.port.

The array_merge_recursive() Trap

Despite its name, array_merge_recursive() is usually not what you want for configuration. When both arrays contain the same string key, it combines the values into an array instead of replacing:

<?php
$defaults = ['db' => ['host' => 'localhost', 'port' => 3306]];
$override = ['db' => ['host' => 'db.prod']];

echo json_encode(array_merge_recursive($defaults, $override)) . "\n";

Output

{"db":{"host":["localhost","db.prod"],"port":3306}}

The host is now an array of two values, which breaks any code expecting a string. Use array_replace_recursive() for "override" semantics. array_merge_recursive() fits only when you really want to collect values — for example, combining lists of tags from several sources under the same key.


array_combine() — Keys From One Array, Values From Another

<?php
$headers = ['sku', 'name', 'price'];
$row = ['PEN-01', 'Gel Pen', '20'];

print_r(array_combine($headers, $row));

Output

Array
(
    [sku] => PEN-01
    [name] => Gel Pen
    [price] => 20
)

This is the standard way to turn a CSV row into an associative record using the header line. Both arrays must contain the same number of elements; otherwise PHP throws a ValueError.


Choosing the Right Tool

GoalUse
Join listsarray_merge() or [...$a, ...$b]
Apply overrides to settings (flat)array_merge($defaults, $overrides) or array_replace()
Fill in missing defaults (flat)$values + $defaults
Keep integer keys (IDs)+ or array_replace()
Override nested configurationarray_replace_recursive()
Collect values under shared keysarray_merge_recursive()
Pair keys with valuesarray_combine()

Practical Example: Layered Configuration

Applications often combine configuration from several layers: built-in defaults, environment-specific settings, and local developer overrides.

<?php
$defaults = [
    'app' => ['name' => 'GoCourse', 'debug' => false],
    'db' => ['host' => 'localhost', 'port' => 3306, 'name' => 'gocourse'],
    'mail' => ['driver' => 'smtp'],
];

$production = [
    'db' => ['host' => 'db.internal'],
    'mail' => ['driver' => 'ses'],
];

$local = [
    'app' => ['debug' => true],
];

$config = array_replace_recursive($defaults, $production, $local);

echo json_encode($config, JSON_PRETTY_PRINT) . "\n";

Output

{
    "app": {
        "name": "GoCourse",
        "debug": true
    },
    "db": {
        "host": "db.internal",
        "port": 3306,
        "name": "gocourse"
    },
    "mail": {
        "driver": "ses"
    }
}

Step-by-Step Explanation

  1. array_replace_recursive() accepts several arrays and applies them from left to right; later layers override earlier ones.
  2. Only the keys present in each layer change: production overrides the database host and mail driver, and the local layer enables debugging.
  3. Every value that no layer overrides (app name, database port and name) comes from the defaults.

With array_merge(), the db section from $production would have replaced the whole default db section, losing the port and database name.


Common Mistakes

Using array_merge() on ID-Keyed Arrays

Effect: IDs are replaced with 0, 1, 2, ….

Fix: Use array_replace() or +.

Using + to Append Lists

Effect: Elements with existing keys are silently dropped.

Fix: Use array_merge() or the spread operator.

Using array_merge_recursive() for Overrides

Effect: Overridden values become arrays of all values.

Fix: Use array_replace_recursive().

Getting the Order Wrong

Effect: array_merge($overrides, $defaults) lets defaults overwrite the user's choices.

Fix: For array_merge()/array_replace(), put the overrides last; for +, put them first.

Merging Inside Loops

Effect: Slow code for large data.

Fix: Collect arrays, then call array_merge(...$arrays) once.


Best Practices

  • Decide how duplicate keys should behave, then choose the function accordingly.
  • Use array_replace_recursive() for nested configuration layers.
  • Preserve meaningful integer keys with array_replace() or +.
  • Merge many arrays in a single array_merge(...$arrays) call.
  • Validate lengths before array_combine().

Official reference: https://www.php.net/manual/en/function.array-merge.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Home PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else Slicing Strings User-defined Functions Slicing Strings PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators AJAX PHP AJAX Database AJAX XML AJAX Live Search AJAX Poll AJAX with JSON Security Introduction Password Hashing SQL Injection Prevention XSS Prevention Garbage Collection Project: Simple Blog PHP What is OOP PHP Classes/Objects The $this Keyword Access Array Items Update Array Items Add Array Items Remove Array Items Sorting Arrays Multidimensional Arrays Array Destructuring Array Spread Operator Search in Arrays Merge Arrays PHP Abstract Classes PHP Interfaces Polymorphism PHP Traits PHP Static Methods PHP Static Properties Late Static Binding Magic Methods Object Cloning
Ask about this post
AI Ask about this post

Ask questions about Merge Arrays and get answers drawn from it.

Signed-in readers only.