array_merge($a, $b) retorna um novo array com os elementos de $a seguidos dos elementos de $b. Chaves numéricas são renumeradas a partir de 0; quando os dois arrays têm a mesma chave string, o valor do array posterior vence. Passe quantos arrays quiser.
O array_merge() não altera os argumentos. Ele retorna o array combinado, então atribua o resultado: $all = array_merge($all, $more);.
Chaves numéricas são renumeradas
O array_merge() trata chaves inteiras como posições, não como nomes. Todo elemento com chave inteira é acrescentado e recebe uma nova chave a partir de 0, mesmo que os arrays usassem os mesmos números ou tivessem buracos. É o que você quer para listas, e uma surpresa quando os números são IDs.
Chaves string que parecem inteiros ('101') são guardadas como inteiros, então também são renumeradas. Chaves como 'id101' continuam como estão.
array_merge ou o operador +
O operador + (união de arrays) também combina arrays, mas com a regra oposta: para qualquer chave que já existe no array da esquerda, o valor da esquerda vence e o da direita é descartado. Ele nunca renumera. Isso faz do + o jeito natural de preencher padrões, e do array_merge() o jeito natural de sobrescrevê-los.
array_merge($a, $b) | $a + $b | |
|---|---|---|
| Mesma chave string | valor de $b | valor de $a |
| Chaves inteiras | renumeradas, todos os valores mantidos | mantidas, $b perde nos conflitos |
| Uso típico | juntar listas, sobrescrever configurações | preencher padrões, manter IDs |
O último exemplo do bloco é a armadilha clássica do +: ['a', 'b'] + ['x', 'y', 'z'] dá a, b, z, porque as chaves 0 e 1 já existem à esquerda.
Sintaxe spread: [...b]
O operador spread desempacota arrays dentro de um literal de array. Ele se comporta como o array_merge(): chaves inteiras são renumeradas e, desde o PHP 8.1, chaves string são permitidas e a posterior vence. Fica legível quando você mistura arrays com valores avulsos.
Para acrescentar um array a outro existente no lugar, veja array_push() com o operador spread.
Juntar um array de arrays
Quando os arrays a combinar estão eles mesmos numa lista, espalhe essa lista no array_merge(). Esse também é o jeito rápido de juntar dentro de um loop: reúna as partes e faça o merge uma vez.
Escrever $all = array_merge($all, $batch); dentro do loop funciona, mas copia o array crescente inteiro a cada volta, o que fica lento com milhares de itens.
array_merge_recursive e array_replace
O array_merge_recursive() também junta arrays aninhados, mas para uma chave string repetida com valores simples ele não sobrescreve: junta os dois valores num novo array. Raramente é o que você quer para configuração. O array_replace_recursive() costuma ser a ferramenta certa ali: ele sobrescreve valores em todos os níveis e mantém as chaves.
Leia as três linhas de JSON de cima para baixo: o array_merge() substituiu o array db inteiro e perdeu host, o array_merge_recursive() transformou port e debug em listas de dois elementos, e o array_replace_recursive() produziu a configuração que você queria.
Erro comum: o merge não remove nada
O array_merge() mantém valores repetidos que estão sob chaves diferentes. Juntar duas listas de tags dá cada tag em comum duas vezes. Passe o resultado por array_unique() e depois por array_values() para renumerar.
A página sobre array_unique explica como remover duplicados de linhas e de arrays aninhados.
Perguntas frequentes
Qual a diferença entre array_merge e + no PHP?
Para chaves string repetidas, array_merge($a, $b) mantém o valor de $b, enquanto $a + $b mantém o valor de $a. Para chaves numéricas, array_merge() acrescenta e renumera tudo, enquanto + mantém as chaves numéricas e descarta qualquer elemento de $b cuja chave já existe em $a.
Como junto arrays mantendo as chaves numéricas?
Use $a + $b se o array da esquerda deve vencer, ou array_replace($a, $b) se o da direita deve vencer. O array_merge() sempre renumera chaves numéricas a partir de 0.
Como junto um array de arrays no PHP?
Espalhe o array externo no array_merge(): $all = array_merge(...$lists);. Ele retorna [] para uma lista vazia. Junte os arrays num loop primeiro e faça o merge uma vez no fim; chamar array_merge() dentro do loop copia o resultado crescente a cada volta.
Posso usar o operador spread com chaves string no PHP?
Sim, desde o PHP 8.1. [...$a, ...$b] então se comporta como array_merge($a, $b): chaves numéricas são renumeradas e uma chave string posterior sobrescreve uma anterior.