Arrays7 min readExamples run on PHP 8.5.10

array_replace()

Learn how PHP array_replace() overlays one or more arrays onto a base array by key, how it differs from array_merge(), and where it surprises people.

Signature

array_replace(array $array, array ...$replacements): array
Available since PHP 5.3.07.48.08.18.28.38.48.5All versions →

Purpose

array_replace() builds a new array by taking a base array and overlaying one or more other arrays on top of it, matching elements by key. When a key exists in the base and in a replacement, the replacement's value wins. When a key exists only in a replacement, it is added. It is a good fit for applying overrides to defaults, patching a record with a few changed fields, or swapping specific positions in a list.

Signature

Parameters and defaults

  • $array: the base array. Its keys and values form the starting point of the result.
  • ...$replacements: zero or more arrays that are applied from left to right. If the same key appears in several of them, the right-most array provides the final value.

There are no optional settings. Passing only the base array is legal and gives you a copy of it.

Return value and failure cases

The function returns a new array. The arrays you pass in are not modified, because arrays are passed by value.

There is no false return for a failure. If any argument is not an array, for example null or a string, PHP throws a TypeError. Convert or validate input with (array) or a type check before you call it.

Example 1: applying overrides to defaults

With string keys, the function behaves like a simple settings overlay. Keys that the override array does not mention keep their original values.

Example
<?php
$defaults = ['theme' => 'light', 'lang' => 'en', 'page_size' => 10];
$user = ['theme' => 'dark', 'page_size' => 25];
$result = array_replace($defaults, $user);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"theme":"dark","lang":"en","page_size":25}

The lang entry survives, while theme and page_size take the user's values. Keys stay in the order of the base array.

Example 2: integer keys are replaced, not renumbered

The most important difference from array_merge() is how numeric keys are handled. array_replace() treats an integer key like any other key, so index 1 in the replacement overwrites index 1 in the base. array_merge() renumbers integer keys and appends the values.

Example
<?php
$base = ['a', 'b', 'c'];
$patch = [1 => 'B', 5 => 'F'];
$replaced = array_replace($base, $patch);
$merged = array_merge($base, $patch);
echo json_encode($replaced, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode($merged, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"0":"a","1":"B","2":"c","5":"F"}
["a","b","c","B","F"]

The replaced array has keys 0, 1, 2 and 5. Because the keys are no longer a sequence starting at zero, json_encode() writes it as an object. The merged array is a clean list of five values, with B and F appended after the original three.

Example 3: values are replaced whole, not merged

The function is shallow. If a value is itself an array, the entire nested array is swapped for the replacement's value. A replacement value of null is still a replacement, so it overwrites the existing value instead of being ignored.

Example
<?php
$base = ['citrus' => ['orange', 'lemon'], 'pome' => ['apple'], 'note' => 'keep'];
$first = ['citrus' => ['grapefruit']];
$second = ['pome' => null];
$result = array_replace($base, $first, $second);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"citrus":["grapefruit"],"pome":null,"note":"keep"}

The citrus list becomes just grapefruit; lemon and orange are gone. The pome entry becomes null, and note is untouched.

Edge cases

  • Key order: existing keys keep their position in the result. Keys that are new are appended in the order they first appear in the replacement arrays.
  • Numeric strings: a key such as "1" is normalized to the integer 1 by PHP's array rules, so it matches integer key 1.
  • No replacements: calling array_replace($a) returns an array equal to $a.
  • Empty arrays: an empty replacement changes nothing. An empty base simply becomes the combined replacements.
  • Several replacements: they are applied one after another, so the last array that contains a key decides its final value.

Common mistakes

  1. Expecting a recursive merge. Nested arrays are not combined. If you need to update just one inner key, use array_replace_recursive() instead.
  2. Using it to append to a list. Because integer keys are matched, array_replace([1, 2], [3]) replaces index 0 and does not append. Use array_merge() or the spread operator when you want to concatenate lists.
  3. Confusing it with the + operator. $a + $b keeps the left value for duplicate keys, which is the opposite of array_replace($a, $b), where the right side wins.
  4. Assuming null means "skip". A null in a replacement overwrites the existing value. Filter out nulls first with array_filter() if that is not what you want.
  5. Passing a non-array. A null or scalar argument raises a TypeError, so cast or validate untrusted input first.
  • array_replace_recursive() replaces values recursively through nested arrays.
  • array_merge() combines arrays but renumbers integer keys and appends them.
  • array_merge_recursive() combines nested values instead of replacing them.

Recap

array_replace() returns a new array in which later arrays overwrite earlier ones key by key, including integer keys. It is shallow, it treats null as a real value, it leaves its inputs unchanged, and it throws a TypeError for non-array arguments. Reach for it when you want overrides by key, and for another function when you want appending or deep merging.

Tested examples

Applying user overrides to default settings
<?php
$defaults = ['theme' => 'light', 'lang' => 'en', 'page_size' => 10];
$user = ['theme' => 'dark', 'page_size' => 25];
$result = array_replace($defaults, $user);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"theme":"dark","lang":"en","page_size":25}
Integer keys: array_replace() versus array_merge()
<?php
$base = ['a', 'b', 'c'];
$patch = [1 => 'B', 5 => 'F'];
$replaced = array_replace($base, $patch);
$merged = array_merge($base, $patch);
echo json_encode($replaced, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode($merged, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"0":"a","1":"B","2":"c","5":"F"}
["a","b","c","B","F"]
Nested arrays and null are replaced whole
<?php
$base = ['citrus' => ['orange', 'lemon'], 'pome' => ['apple'], 'note' => 'keep'];
$first = ['citrus' => ['grapefruit']];
$second = ['pome' => null];
$result = array_replace($base, $first, $second);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"citrus":["grapefruit"],"pome":null,"note":"keep"}