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 +.
