array_merge vs array_replace vs + en PHP: cuándo combinar arrays de cada forma

PHP tiene tres formas de combinar arrays y cada una se comporta de manera diferente ante las claves duplicadas y los arrays numéricos: array_merge() renumera las claves numéricas y los valores del segundo array sobreescriben los del primero en claves de string; el operador + hace lo contrario (prevalece el primero); y array_replace() hace una sustitución explícita por clave. Confundirlas es una fuente habitual de bugs silenciosos.

array_merge(): el más común, con sus sorpresas

<?php
// Claves numéricas: se renumeran siempre
$a = [0 => 'manzana', 1 => 'pera'];
$b = [0 => 'naranja', 1 => 'limón'];

$merged = array_merge($a, $b);
print_r($merged);
// Array ( [0] => manzana [1] => pera [2] => naranja [3] => limón )
// CUATRO elementos, claves renumeradas correlativamente

// Claves de string: el segundo sobreescribe al primero
$config_base = ['host' => 'localhost', 'puerto' => 3306, 'charset' => 'utf8mb4'];
$config_prod = ['host' => 'db.ejemplo.com', 'puerto' => 5432];

$config = array_merge($config_base, $config_prod);
print_r($config);
// Array ( [host] => db.ejemplo.com [puerto] => 5432 [charset] => utf8mb4 )
?>

El operador +: prevalece el primero

El operador + es la operación contraria: si la clave ya existe en el array izquierdo, se ignora el valor del derecho. En claves numéricas no renumera:

<?php
$defaults = ['color' => 'azul', 'tamaño' => 'M', 'stock' => 0];
$entrada  = ['color' => 'rojo', 'peso' => '250g'];

// Con +: los valores de $entrada no sobreescriben los de $defaults
$resultado = $entrada + $defaults;
print_r($resultado);
// Array ( [color] => rojo [peso] => 250g [tamaño] => M [stock] => 0 )
// 'color' toma el valor de $entrada (el izquierdo)

// En claves numéricas + no renumera
$x = [0 => 'a', 2 => 'c'];
$y = [0 => 'X', 1 => 'Y', 2 => 'Z'];
print_r($x + $y);
// Array ( [0] => a [2] => c [1] => Y )
// Las claves 0 y 2 ya existen en $x, solo añade la clave 1 de $y
?>

array_replace(): sustitución explícita por clave

array_replace() reemplaza los valores del primer array con los del segundo basándose en las claves. No añade claves que no existan en el primero (a diferencia de array_merge()):

<?php
$base    = ['a' => 1, 'b' => 2, 'c' => 3];
$cambios = ['b' => 20, 'd' => 40]; // 'd' no existe en $base

$resultado = array_replace($base, $cambios);
print_r($resultado);
// Array ( [a] => 1 [b] => 20 [c] => 3 [d] => 40 )
// Nota: en array_replace SÍ añade 'd' aunque no estaba en $base
// La diferencia está en arrays numéricos (no renumera)
?>

array_merge_recursive con subarrays anidados

<?php
$permisos_rol  = ['php' => ['leer', 'escribir'], 'admin' => ['acceder']];
$permisos_user = ['php' => ['publicar'],         'blog'  => ['leer']];

// array_merge: 'php' del segundo sobreescribe al primero
print_r(array_merge($permisos_rol, $permisos_user));
// Array ( [php] => Array ( [0] => publicar ) [admin] => Array ( [0] => acceder ) [blog] => Array ( [0] => leer ) )

// array_merge_recursive: agrupa en subarrays cuando hay coincidencia de clave
print_r(array_merge_recursive($permisos_rol, $permisos_user));
// Array ( [php] => Array ( [0] => leer [1] => escribir [2] => publicar ) [admin] => ... [blog] => ... )
?>

Resumen rápido

  • Necesitas unir dos listas y que se renumeren: usa array_merge()
  • Quieres aplicar valores por defecto que no sobreescriban los ya existentes: usa +
  • Necesitas que el segundo sobreescriba al primero sin renumerar claves numéricas: usa array_replace()
  • Necesitas fusionar arrays anidados acumulando valores: usa array_merge_recursive()

La documentación oficial de array_merge() y la de array_replace() incluyen las diferencias detalladas con el operador +.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP