Lesson 53 of 100
Arrays15 min5 checksPHP 8.5

Merge Arrays and Replace Keys

Learn how array_merge() treats string and numeric keys differently, and how it compares with the + operator and array_replace().

01 · THE IDEAREAD → TRY → LEARN

Why key type matters

A PHP array is an ordered map, and every element has a key that is either an integer or a string. When you combine two arrays, those keys decide what happens to the values. The same-looking operation can overwrite, append, or renumber depending on the key type, so merge code needs to be intentional.

The main tool is array_merge(array ...$arrays): array. It takes any number of arrays and returns a new array. The inputs are not modified. Since PHP 7.4 you can call it with no arguments, and it returns an empty array.

The two rules

  1. String keys: if the same string key appears in more than one input, the later value wins.
  2. Numeric keys: values are never overwritten. They are appended in order and renumbered from zero.

The first rule makes array_merge() a good fit for settings, where defaults come first and overrides come second.

Example
<?php
$defaults = ['theme' => 'light', 'lang' => 'en'];
$overrides = ['theme' => 'dark'];

echo json_encode(array_merge($defaults, $overrides), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
{"theme":"dark","lang":"en"}

The theme value from the second array replaced the first one. The lang key was kept because nothing overrode it.

Numeric keys are renumbered

The second rule surprises many people. A numeric key is treated as a position in a list, not as an identity. Two values that share the key 5 are both kept, and the key itself disappears.

Example
<?php
echo json_encode(array_merge([], [1 => 'data']), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
echo json_encode(array_merge([5 => 'a'], [5 => 'b']), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
["data"]
["a","b"]

Both results are plain lists. If the integer keys meant something, such as database ids, array_merge() throws that information away.

Three ways to combine, three results

PHP offers other ways to combine arrays, and each one handles numeric keys differently:

  • array_merge($a, $b) appends numeric keys and renumbers them.
  • $a + $b keeps the first array's value whenever a key exists in both. Keys are preserved.
  • array_replace($a, $b) copies values from later arrays into the first one by key. A later value wins for any matching key, numeric or string.

The next example runs all three on the same input.

Example
<?php
$a = [0 => 'zero_a', 2 => 'two_a', 3 => 'three_a'];
$b = [1 => 'one_b', 3 => 'three_b', 4 => 'four_b'];
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;

echo json_encode(array_merge($a, $b), $flags), PHP_EOL;
echo json_encode($a + $b, $flags), PHP_EOL;
echo json_encode(array_replace($a, $b), $flags), PHP_EOL;
Output
["zero_a","two_a","three_a","one_b","three_b","four_b"]
{"0":"zero_a","2":"two_a","3":"three_a","1":"one_b","4":"four_b"}
{"0":"zero_a","2":"two_a","3":"three_b","1":"one_b","4":"four_b"}

The merged result is a clean six-item list. The union keeps three_a, while array_replace() yields three_b. Those last two results are encoded as JSON objects because their integer keys are not a sequence starting at zero.

Choosing the right operation

Ask what the keys mean:

  • If the arrays are lists and you want every item, use array_merge().
  • If string keys are settings and the second array should win, use array_merge() or array_replace().
  • If the first array should win and you want to fill gaps, use +.
  • If integer keys are identities that must survive, use array_replace() or +, not array_merge().

Edge cases and mistakes

  • Merging two empty arrays gives an empty array.
  • Argument order matters for string keys. Swapping defaults and overrides silently reverses who wins.
  • A numeric-looking string key such as '7' becomes the integer key 7 in a PHP array, so it follows the numeric rule.
  • array_merge() is shallow. Nested arrays under a string key are replaced whole, not combined. The related array_merge_recursive() exists for other behavior, but use it carefully.

Exercise contract

Write mergeSettings(array $defaults, array $overrides): array. It returns a new array in which string keys from $overrides replace those in $defaults, new string keys are added, and numeric-keyed values are appended and renumbered. The function must not print anything. It must return the array. The five tests cover overriding, list appending, renumbering a lone numeric key, new keys, and empty input.

Recap

array_merge() overwrites on string keys and appends with renumbering on numeric keys. + keeps the first value, and array_replace() replaces by key. Pick the one that matches what your keys mean.

Before you start

Functions · Arrays · Types

You’ll practice
  • Handle numeric and string keys intentionally
  • Implement and test a deterministic PHP 8.4 function
Your task

Make mergeSettings() pass all 5 checks. Run your code as often as you like, then check your answer.

exercise.phpSaved in this browserPHP 8.5
CONSOLE & CHECKS● Ready

Ready when you are

Your output will appear here.
Make it work. Then make it pass.

PHP loads on your first run. Each check starts fresh. Your code stays in this browser; clearing site data removes your progress. A check or the task looks wrong? Report a problem with this exercise.