O Guia Definitivo de Arrays em PHP (PHP 8.4+) - Todas as Funções Explicadas
quinta-feira, 9 de julho de 2026
Aprenda tudo sobre arrays em PHP: arrays indexados, associativos e multidimensionais, array_map(), array_filter(), array_reduce(), desempenho, boas práticas e exemplos do mundo real.
Tabela de Conteúdos
- Introdução
- 1. O que é um Array?
- 2. Como os Arrays do PHP Funcionam Internamente
- 3. Arrays Indexados
- 4. Arrays Associativos
- 5. Arrays Multidimensionais
- 6. Percorrendo Arrays
- 7. Transformando Arrays
- 8. Combinando Arrays
- 9. Ordenando Arrays
- 10. Pesquisando em Arrays
- 11. Desestruturação de Arrays (Array Destructuring)
- 12. Operador de Espalhamento (Spread Operator)
- 13. Desempenho
- 14. Erros Comuns
- 15. Boas Práticas
- 16. Exemplos Reais em Produção
- 17. Perguntas Frequentes (FAQ)
- Os arrays do PHP preservam a ordem dos elementos?
- Os arrays do PHP são tabelas hash?
- Qual é a diferença entre arrays indexados e arrays associativos?
- array_map() é mais rápido que foreach?
- Quando devo utilizar array_reduce()?
- Por que array_filter() remove 0 e strings vazias?
- Qual a diferença entre isset() e array_key_exists()?
- Atribuir um array para outra variável cria uma cópia?
- Por que arrays do PHP consomem tanta memória?
- Devo utilizar arrays ou objetos?
- Conclusão
Introdução
Todo desenvolvedor PHP utiliza arrays.
Seja lendo dados de um banco de dados, consumindo uma API REST, processando JSON, manipulando requisições HTTP ou simplesmente armazenando uma lista de valores, os arrays estão por toda parte. Na verdade, diversos recursos internos da linguagem --- incluindo as superglobais como $_GET, $_POST e $_SERVER --- nada mais são do que arrays.
Apesar de serem uma das estruturas de dados mais utilizadas do PHP, os arrays também estão entre os recursos mais mal compreendidos da linguagem.
Muitos desenvolvedores aprendem a criar um array e percorrê-lo com foreach, mas param por aí. Poucos exploram as dezenas de funções nativas disponíveis, compreendem como os arrays funcionam internamente ou percebem que determinadas escolhas podem tornar o código mais lento, menos legível e desnecessariamente complexo.
Entender arrays em um nível mais profundo muda completamente a forma como você escreve código em PHP. Em vez de enxergá-los apenas como recipientes para armazenar valores, você passa a utilizá-los como uma das ferramentas mais poderosas da linguagem para transformar, organizar e processar dados de forma eficiente.
Neste guia você aprenderá tudo o que precisa saber sobre arrays em PHP, incluindo:
- Arrays indexados, associativos e multidimensionais;
- Como os arrays funcionam internamente;
- As principais funções da biblioteca padrão;
- Recursos de programação funcional, como
array_map(),array_filter()earray_reduce(); - Considerações sobre desempenho;
- Armadilhas e erros comuns;
- Boas práticas utilizadas em aplicações de produção.
Todos os exemplos deste artigo utilizam PHP 8.4+, embora a maior parte dos conceitos também seja válida para versões anteriores da linguagem.
Se você está começando a aprender PHP ou já trabalha com a linguagem há anos, este guia ajudará você a escrever um código mais limpo, mais expressivo e mais eficiente.
1. O que é um Array?
Se você vem de linguagens como C, Java ou C#, provavelmente imagina um array como uma sequência de elementos de tamanho fixo armazenados em posições contíguas da memória.
Os arrays do PHP são fundamentalmente diferentes.
Segundo a documentação oficial do PHP, um array é um ordered map (mapa ordenado). Embora essa definição possa parecer um pouco abstrata à primeira vista, ela descreve perfeitamente por que os arrays do PHP são tão flexíveis.
Um ordered map é uma coleção de pares chave-valor (key-value pairs) na qual a ordem de inserção dos elementos é preservada.
Cada elemento é composto por:
- uma chave (key), utilizada para identificar o valor;
- um valor (value), que pode ser praticamente qualquer tipo de dado suportado pelo PHP.
Por exemplo:
$colors = [
"red",
"green",
"blue",
];
Embora nenhuma chave tenha sido definida explicitamente, o PHP atribui automaticamente índices inteiros começando em zero.
Internamente, esse array equivale a:
[
0 => "red",
1 => "green",
2 => "blue",
]
As chaves não precisam ser obrigatoriamente números inteiros.
Elas também podem ser strings, permitindo que arrays representem dicionários, objetos de configuração, registros de banco de dados, documentos JSON, cabeçalhos HTTP e diversos outros tipos de estruturas de dados.
$user = [
"name" => "John Doe",
"email" => "john@example.com",
"age" => 32,
];
Uma das maiores vantagens do PHP é que arrays indexados e arrays associativos utilizam exatamente a mesma estrutura de dados internamente. Você não precisa escolher coleções diferentes dependendo do problema que deseja resolver.
Além disso, um array pode conter outros arrays, permitindo representar estruturas hierárquicas ou dados aninhados.
$company = [
"name" => "Acme Inc.",
"employees" => [
[
"name" => "Alice",
"role" => "Developer",
],
[
"name" => "Bob",
"role" => "Designer",
],
],
];
Outra característica importante é que os arrays do PHP são heterogêneos, ou seja, podem armazenar diferentes tipos de dados simultaneamente.
$data = [
42,
"Hello",
true,
3.14,
null,
];
Embora essa flexibilidade seja extremamente conveniente, em geral é uma boa prática manter os arrays o mais homogêneos possível. Coleções que misturam muitos tipos de dados tendem a se tornar mais difíceis de compreender, validar e manter ao longo do tempo.
Como veremos ao longo deste guia, os arrays do PHP são muito mais do que simples listas de valores: eles constituem uma das bases sobre as quais praticamente toda a linguagem foi construída.
2. Como os Arrays do PHP Funcionam Internamente
A maioria dos desenvolvedores utiliza arrays todos os dias sem nunca se perguntar o que acontece nos bastidores.
Você não precisa conhecer os detalhes internos do PHP para escrever um bom código. No entanto, ter uma compreensão básica de como os arrays funcionam ajuda a explicar diversos comportamentos que, à primeira vista, podem parecer surpreendentes.
Ao contrário dos arrays de linguagens como C, os arrays do PHP não são blocos contíguos de memória.
Em vez disso, eles são implementados como tabelas hash ordenadas (ordered hash tables).
Esse projeto permite que um único tipo de estrutura de dados ofereça simultaneamente:
- chaves inteiras;
- chaves do tipo string;
- geração automática de índices;
- buscas rápidas por chave;
- preservação da ordem de inserção;
- redimensionamento dinâmico.
É uma quantidade impressionante de flexibilidade para uma única estrutura de dados.
Uma visão simplificada seria:
Função Hash
│
▼
┌────────────┐
"name" ─▶│ Bucket │──▶ "John"
└────────────┘
"age" ──▶│ Bucket │──▶ 32
"city" ─▶│ Bucket │──▶ "London"
Quando você acessa:
echo $user["name"];
o PHP não percorre todo o array procurando pela chave "name".
Em vez disso, calcula o hash da chave, acessa diretamente o bucket correspondente e recupera o valor. É por isso que buscas por chave costumam ser extremamente rápidas.
Outra característica importante é que o PHP preserva a ordem em que os elementos foram inseridos.
$data = [];
$data["c"] = 1;
$data["a"] = 2;
$data["b"] = 3;
Ao percorrer esse array, a saída será:
c
a
b
e não em ordem alfabética.
Esse comportamento torna os arrays previsíveis na geração de JSON, renderização de HTML, processamento de arquivos de configuração e consumo de APIs.
O PHP também utiliza uma otimização chamada Copy-on-Write (CoW).
Considere:
$a = [1, 2, 3];
$b = $a;
À primeira vista parece que o array foi copiado.
Na verdade, não.
Inicialmente, ambas as variáveis apontam para a mesma estrutura interna. Uma cópia real só é criada quando uma delas é modificada.
$b[] = 4;
Somente nesse momento o PHP aloca uma nova região de memória para $b.
Sem o Copy-on-Write, passar arrays para funções ou atribuí-los a outras variáveis seria significativamente mais caro.
Essa otimização é uma das razões pelas quais o PHP continua apresentando um excelente desempenho mesmo em aplicações que manipulam muitos arrays.
Naturalmente, toda essa flexibilidade tem um custo: arrays do PHP consomem consideravelmente mais memória do que arrays de baixo nível encontrados em linguagens como C ou Rust, pois cada elemento armazena metadados além do próprio valor.
Para a grande maioria das aplicações web, entretanto, esse custo compensa amplamente. A sintaxe expressiva, as buscas rápidas e a rica biblioteca padrão fazem dos arrays uma das funcionalidades mais produtivas da linguagem.
3. Arrays Indexados
Os arrays indexados são o tipo de array mais simples e mais utilizado no PHP.
Eles armazenam valores utilizando chaves inteiras, sendo ideais quando a posição de cada elemento é mais importante do que um nome descritivo.
Criar um array indexado é bastante simples.
$languages = [
"PHP",
"JavaScript",
"Python",
"Go",
];
O PHP atribui automaticamente índices sequenciais iniciando em zero.
Internamente, esse array equivale a:
$languages = [
0 => "PHP",
1 => "JavaScript",
2 => "Python",
3 => "Go",
];
Você pode acessar qualquer elemento utilizando seu índice.
echo $languages[0]; // PHP
echo $languages[2]; // Python
Adicionar novos elementos também é simples.
$languages[] = "Rust";
O PHP atribui automaticamente o próximo índice disponível.
Também é possível definir índices manualmente.
$numbers = [
10 => "ten",
20 => "twenty",
];
Ao adicionar um novo elemento:
$numbers[] = "thirty";
o índice atribuído será 21, e não 2.
Esse comportamento costuma surpreender quem está começando.
O PHP sempre continua a partir da maior chave inteira existente.
Atualizar valores funciona exatamente como esperado.
$languages[1] = "TypeScript";
Para remover elementos, utilize unset().
unset($languages[2]);
Existe, porém, um detalhe importante: remover um elemento não reindexa automaticamente o array.
Após a remoção, teremos:
[
0 => "PHP",
1 => "TypeScript",
3 => "Go",
4 => "Rust",
]
Observe que o índice 2 deixou de existir.
Caso você precise que os índices voltem a ser sequenciais, utilize
array_values().
$languages = array_values($languages);
Resultado:
[
0 => "PHP",
1 => "TypeScript",
2 => "Go",
3 => "Rust",
]
Na maioria dos casos, você não deve depender de índices consecutivos. Diversas funções do PHP preservam as chaves intencionalmente, e reindexar grandes arrays sem necessidade apenas adiciona processamento.
A forma mais comum de percorrer um array indexado é utilizando foreach.
foreach ($languages as $language) {
echo $language . PHP_EOL;
}
Caso também precise do índice:
foreach ($languages as $index => $language) {
echo "{$index}: {$language}" . PHP_EOL;
}
Embora sejam frequentemente utilizados como listas simples, os arrays indexados também servem de base para praticamente todas as operações que veremos nos próximos capítulos, incluindo transformação, filtragem, ordenação, agrupamento e redução de dados. Dominar esses conceitos tornará as funções mais avançadas do PHP muito mais naturais de utilizar.
4. Arrays Associativos
Enquanto os arrays indexados organizam os dados por posições numéricas, os arrays associativos organizam as informações utilizando chaves nomeadas.
Em vez de perguntar "Qual é o terceiro elemento?", você passa a perguntar "Qual é o e-mail do usuário?" ou "Qual é o preço do produto?". Isso torna os arrays associativos muito mais expressivos e explica por que eles são tão utilizados em aplicações PHP.
Criar um array associativo é simples:
$user = [
"name" => "John Doe",
"email" => "john@example.com",
"age" => 32,
];
Os valores são acessados por meio de suas chaves.
echo $user["name"];
echo $user["email"];
Atualizar um valor existente funciona exatamente como esperado.
$user["age"] = 33;
Adicionar novos elementos também é bastante simples.
$user["country"] = "Canada";
Para remover uma chave, utilize unset().
unset($user["age"]);
Diferentemente de muitas linguagens de programação, o PHP não possui um tipo específico para dicionários ou mapas. Os arrays associativos desempenham esse papel utilizando exatamente a mesma estrutura de dados empregada pelos arrays indexados.
Essa flexibilidade faz com que sejam ideais para representar informações estruturadas.
Um objeto de configuração:
$config = [
"host" => "localhost",
"port" => 3306,
"database" => "blog",
];
Cabeçalhos HTTP:
$headers = [
"Content-Type" => "application/json",
"Accept" => "application/json",
];
Um registro de banco de dados:
$product = [
"id" => 15,
"name" => "Mechanical Keyboard",
"price" => 129.90,
];
Ou o resultado da decodificação de uma resposta JSON:
$response = json_decode($json, true);
O segundo parâmetro (true) informa ao json_decode() que o retorno deve ser um array associativo em vez de um objeto --- um padrão extremamente comum em aplicações PHP modernas.
Como as chaves possuem significado semântico, arrays associativos normalmente produzem um código muito mais legível do que depender de índices numéricos.
Compare:
$user[0];
$user[1];
$user[2];
com:
$user["name"];
$user["email"];
$user["age"];
A segunda versão é imediatamente compreensível, sem necessidade de comentários ou documentação adicional.
Outro detalhe importante é que as chaves de um array são únicas. Se um valor for atribuído a uma chave já existente, o valor anterior será substituído.
$user["name"] = "Alice";
$user["name"] = "Bob";
Ao final, o array conterá apenas "Bob".
Embora sejam extremamente convenientes, arrays associativos podem acabar sendo utilizados em excesso. Se um array passa a conter dezenas de campos, estruturas aninhadas, regras de validação e lógica de negócio, talvez seja o momento de substituí-lo por uma classe ou um Data Transfer Object (DTO).
5. Arrays Multidimensionais
Os arrays do PHP podem armazenar qualquer tipo de valor --- inclusive outros arrays.
Quando um array contém um ou mais arrays em seu interior, ele é chamado de array multidimensional.
Esse tipo de estrutura é extremamente comum porque os dados do mundo real raramente são planos.
Imagine uma aplicação de e-commerce.
Um único pedido contém informações do cliente, dados de entrega e uma lista de produtos comprados.
Representar esse cenário com arrays multidimensionais é bastante natural.
$order = [
"id" => 1001,
"customer" => [
"name" => "John Doe",
"email" => "john@example.com",
],
"items" => [
[
"product" => "Keyboard",
"quantity" => 2,
"price" => 129.90,
],
[
"product" => "Mouse",
"quantity" => 1,
"price" => 49.90,
],
],
];
Acessar valores aninhados significa apenas encadear índices.
echo $order["customer"]["name"];
echo $order["items"][0]["product"];
Da mesma forma, atualizar valores profundamente aninhados também é simples.
$order["items"][1]["quantity"] = 3;
Uma das maiores fontes de arrays multidimensionais no PHP é o JSON.
Considere a seguinte resposta de uma API:
{
"name": "John",
"roles": ["admin", "editor"],
"address": {
"city": "London",
"country": "UK"
}
}
Após decodificá-la:
$data = json_decode($json, true);
o resultado será simplesmente um array associativo multidimensional.
Compreender estruturas aninhadas é essencial para trabalhar com APIs REST, arquivos de configuração, bancos de dados, filas de processamento e praticamente qualquer aplicação web moderna.
À medida que os níveis de aninhamento aumentam, entretanto, a legibilidade tende a diminuir.
Compare:
$data["users"][4]["orders"][8]["products"][2]["price"];
com um modelo de objetos bem projetado.
Embora arrays multidimensionais sejam excelentes para transportar e transformar dados, normalmente eles não são a melhor escolha para representar modelos de domínio complexos. Conforme a aplicação cresce, estruturas profundamente aninhadas tornam-se mais difíceis de validar, documentar e manter.
Uma regra prática bastante útil é:
- Utilize arrays para representar dados.
- Utilize objetos para representar comportamentos.
Ter essa distinção em mente ajuda a construir aplicações muito mais organizadas e fáceis de evoluir ao longo do tempo.
6. Percorrendo Arrays
Criar arrays é apenas metade do trabalho.
Na maioria das aplicações, passamos muito mais tempo lendo, processando e transformando arrays do que simplesmente criando-os.
O PHP oferece diversas maneiras de percorrer arrays, cada uma mais adequada para determinados cenários.
foreach
A instrução foreach é, de longe, a forma mais comum, elegante e expressiva de percorrer arrays.
foreach ($languages as $language) {
echo $language;
}
Caso você também precise das chaves:
foreach ($user as $key => $value) {
echo "{$key}: {$value}" . PHP_EOL;
}
Como o foreach foi projetado especificamente para arrays e objetos percorríveis (Traversable), ele deve ser, quase sempre, sua primeira escolha.
Além de ser mais legível e conciso, evita diversos erros comuns relacionados ao controle manual de índices.
for
O tradicional laço for também pode ser utilizado com arrays indexados.
for ($i = 0; $i < count($languages); $i++) {
echo $languages[$i];
}
Entretanto, chamar count() diretamente na condição do laço faz com que a função seja executada a cada iteração.
Uma pequena melhoria consiste em armazenar o tamanho do array antes do loop.
$count = count($languages);
for ($i = 0; $i < $count; $i++) {
echo $languages[$i];
}
Mesmo assim, na maioria dos casos o foreach continua sendo a opção mais indicada por ser mais simples, mais legível e menos propenso a erros.
Percorrendo por Referência
Em algumas situações você precisa modificar cada elemento do array durante a iteração.
Para isso, o PHP permite percorrer os elementos por referência.
foreach ($numbers as &$number) {
$number *= 2;
}
Nesse caso, os valores do próprio array são modificados.
Entretanto, referências exigem bastante cuidado.
Um erro muito comum é esquecer de remover a referência após o término do laço.
unset($number);
Caso isso não seja feito, $number continuará apontando para o último elemento do array, podendo provocar bugs extremamente difíceis de identificar posteriormente.
Esse é um daqueles comportamentos do PHP que surpreendem até mesmo desenvolvedores experientes.
array_walk_recursive()
Diferentemente do array_walk(), que percorre apenas o primeiro nível do array, array_walk_recursive() percorre todos os arrays aninhados, visitando todos os valores finais (leaf values), independentemente da profundidade da estrutura.
Considere o seguinte exemplo:
$data = [
"user" => [
"name" => "John Doe",
"email" => "john@example.com",
],
"address" => [
"city" => "London",
"country" => "United Kingdom",
],
"roles" => [
"admin",
"editor",
],
];
Utilizando array_walk_recursive():
array_walk_recursive(
$data,
function ($value, $key) {
echo "{$key}: {$value}" . PHP_EOL;
}
);
O resultado será:
name: John Doe
email: john@example.com
city: London
country: United Kingdom
0: admin
1: editor
Observe que o callback é executado apenas para os valores finais da estrutura.
Ele não visita arrays intermediários, como "user" ou "address".
Essa diferença é importante porque muitos desenvolvedores imaginam que ele funcione como um foreach recursivo, o que não acontece.
Um caso de uso bastante comum é normalizar dados recebidos de fontes externas.
Por exemplo, remover espaços em branco de todas as strings de uma estrutura complexa:
array_walk_recursive(
$data,
function (&$value) {
if (is_string($value)) {
$value = trim($value);
}
}
);
Outro uso frequente é escapar recursivamente dados antes de gerar HTML ou exportar informações.
Apesar de ser extremamente conveniente, array_walk_recursive() não resolve todos os problemas envolvendo estruturas recursivas.
Como ele fornece acesso apenas aos valores finais, não pode ser utilizado quando você precisa:
- remover ramos inteiros da estrutura;
- renomear chaves;
- reorganizar o array;
- acessar elementos "pais" durante a recursão.
Nesses cenários, normalmente vale mais a pena implementar uma função recursiva personalizada.
Felizmente, essas situações são relativamente raras. Na maioria das aplicações, um simples foreach ou as funções de transformação apresentadas a seguir são suficientes.
7. Transformando Arrays
Criar arrays é fácil.
O verdadeiro desafio começa depois.
Imagine uma aplicação que carrega 10.000 produtos de um banco de dados.
Raramente esses dados serão utilizados exatamente da forma como foram retornados.
Em vez disso, normalmente será necessário:
- converter preços;
- remover produtos inativos;
- calcular totais;
- agrupar registros;
- extrair determinados campos;
- preparar uma resposta para uma API.
Em outras palavras, você passará muito mais tempo transformando arrays do que criando-os.
O PHP reconhece essa necessidade e disponibiliza dezenas de funções nativas voltadas especificamente para manipulação de arrays. Aprender essas funções é um dos maiores ganhos de produtividade que um desenvolvedor PHP pode obter.
Considere o seguinte array:
$numbers = [1, 2, 3, 4, 5];
Dependendo do seu objetivo, existem três tipos fundamentais de transformação.
Transformar todos os elementos
Imagine que você queira elevar todos os números ao quadrado.
O resultado esperado seria:
[
1,
4,
9,
16,
25,
]
Nenhum elemento foi removido.
Nenhum elemento foi combinado.
Cada valor de entrada gerou exatamente um novo valor de saída.
Esse tipo de operação é conhecido como mapping.
Manter apenas alguns elementos
Agora imagine que você queira manter apenas os números pares.
O resultado seria:
[
2,
4,
]
O array original continua existindo.
Apenas alguns elementos foram descartados de acordo com uma condição.
Esse processo é conhecido como filtering.
Produzir um único resultado
Em outras situações, o array em si não é o objetivo final.
Você deseja apenas um resumo dos dados.
Por exemplo:
15
onde 15 representa a soma de todos os números.
Ou talvez:
- a média;
- o maior valor;
- o valor total de um pedido;
- um relatório;
- um novo array associativo indexado por ID.
Esse tipo de operação recebe o nome de reducing, pois vários elementos são reduzidos a um único resultado.
Esses três conceitos são tão comuns que o PHP fornece funções específicas para cada um deles.
| Objetivo | Função |
|----------|---------|
| Transformar todos os elementos | array_map() |
| Manter apenas alguns elementos | array_filter() |
| Combinar vários elementos em um único resultado | array_reduce() |
Depois que você aprende a reconhecer esses padrões, começa a encontrá-los em praticamente todas as linguagens modernas, como JavaScript, Python, Java, C#, Kotlin, Rust e muitas outras.
Os nomes podem variar, mas os conceitos permanecem exatamente os mesmos.
Por isso, dominar essas operações melhora suas habilidades como programador muito além do PHP.
Por que não usar apenas foreach?
Nesse ponto, talvez você esteja se perguntando por que essas funções existem.
Afinal, tudo o que vimos até agora poderia ser implementado utilizando apenas um foreach.
Por exemplo:
$result = [];
foreach ($numbers as $number) {
$result[] = $number * $number;
}
Esse código está absolutamente correto.
Aliás, em muitos cenários ele é justamente a solução mais clara.
Entretanto, quando você passa a conhecer as funções de manipulação de arrays do PHP, o código passa a expressar muito melhor sua intenção.
Em vez de descrever como realizar cada passo da operação, você descreve o que deseja obter.
Essa mudança geralmente produz um código mais fácil de ler, revisar e manter.
Esse estilo é conhecido como programação declarativa, em oposição ao estilo imperativo, representado pelos laços tradicionais.
Nenhuma das abordagens é universalmente melhor.
Bons desenvolvedores dominam ambas.
O importante é escolher aquela que comunica a intenção do código da forma mais clara possível.
Escolhendo a ferramenta correta
Um erro bastante comum entre desenvolvedores que descobrem programação funcional é tentar substituir todo foreach por array_map() ou array_reduce().
Na maioria das vezes, essa não é uma boa ideia.
Uma regra prática bastante útil é:
- Utilize
foreachquando a operação possui efeitos colaterais, como gravar arquivos, enviar e-mails, registrar logs ou modificar objetos. - Utilize
array_map()quando cada elemento deve gerar exatamente outro elemento. - Utilize
array_filter()quando alguns elementos precisam ser removidos. - Utilize
array_reduce()quando vários elementos devem produzir um único resultado.
Forçar uma função de transformação em um problema inadequado normalmente produz um código engenhoso, porém difícil de compreender.
A legibilidade deve ser sempre a prioridade.
Nos próximos capítulos exploraremos cada uma dessas funções em detalhes, entenderemos como elas funcionam internamente, compararemos seu comportamento com laços tradicionais, analisaremos questões de desempenho e veremos diversos exemplos reais extraídos de aplicações de produção.
8. Combinando Arrays
Combinar arrays é uma das operações mais comuns em PHP.
Seja unindo arquivos de configuração, agregando respostas de APIs, construindo parâmetros de consultas (query parameters) ou compondo configurações da aplicação, em algum momento você precisará juntar dois ou mais arrays em uma única estrutura.
Embora o PHP ofereça diversas formas de fazer isso, elas não são equivalentes. Escolher a abordagem errada pode produzir resultados inesperados, principalmente quando arrays associativos ou chaves numéricas estão envolvidos.
As três técnicas mais utilizadas são:
array_merge();- o operador de união de arrays (
+); - o operador de espalhamento (spread operator) (
...).
Entender as diferenças entre elas é fundamental.
array_merge()
A função array_merge() concatena um ou mais arrays, produzindo um novo array.
$backend = [
"PHP",
"MySQL",
];
$frontend = [
"JavaScript",
"CSS",
];
$result = array_merge($backend, $frontend);
print_r($result);
Resultado:
Array
(
[0] => PHP
[1] => MySQL
[2] => JavaScript
[3] => CSS
)
Quando arrays associativos possuem a mesma chave, o último valor prevalece.
$config = [
"host" => "localhost",
"port" => 3306,
];
$override = [
"port" => 3307,
];
$result = array_merge($config, $override);
Resultado:
[
"host" => "localhost",
"port" => 3307,
]
Já nos arrays indexados existe um detalhe importante: array_merge() sempre reindexa as chaves numéricas.
$a = [
5 => "PHP",
];
$b = [
8 => "JavaScript",
];
$result = array_merge($a, $b);
Resultado:
[
0 => "PHP",
1 => "JavaScript",
]
Esse comportamento costuma surpreender muitos desenvolvedores, que esperam que os índices originais sejam preservados.
Operador de União (+)
O operador + realiza uma união de arrays, e não uma concatenação (merge).
$a = [
"name" => "John",
"email" => "john@example.com",
];
$b = [
"email" => "john.doe@example.com",
"country" => "Canada",
];
$result = $a + $b;
Resultado:
[
"name" => "John",
"email" => "john@example.com",
"country" => "Canada",
]
Observe o que aconteceu:
- as chaves já existentes no array da esquerda foram preservadas;
- valores conflitantes do array da direita foram ignorados.
Uma boa forma de pensar no operador + é:
"Mantenha tudo o que existe no primeiro array e adicione apenas as chaves que ainda não existem."
Outra diferença importante é que, ao contrário do array_merge(), as chaves numéricas também são preservadas.
$a = [
5 => "PHP",
];
$b = [
8 => "JavaScript",
];
$result = $a + $b;
Resultado:
[
5 => "PHP",
8 => "JavaScript",
]
Operador de Espalhamento (...)
Introduzido para arrays no PHP 7.4 e aprimorado nas versões posteriores, o operador de espalhamento (spread operator) oferece uma sintaxe bastante elegante para combinar arrays.
$backend = ["PHP", "MySQL"];
$frontend = ["JavaScript", "CSS"];
$languages = [
...$backend,
...$frontend,
];
Resultado:
[
"PHP",
"MySQL",
"JavaScript",
"CSS",
]
Ele também pode ser combinado com novos valores.
$languages = [
"HTML",
...$frontend,
"TypeScript",
];
Em arrays associativos, as versões modernas do PHP apresentam um comportamento semelhante ao array_merge().
$config = [
...$defaults,
...$environment,
];
Essa sintaxe vem se tornando cada vez mais popular por ser extremamente concisa e fácil de ler, especialmente durante a construção de arrays.
Qual abordagem utilizar?
Embora essas três alternativas pareçam semelhantes, elas possuem objetivos diferentes.
| Operação | Chaves existentes | Chaves numéricas |
|----------|-------------------|------------------|
| array_merge() | sobrescritas pelos arrays posteriores | reindexadas |
| + | preservadas a partir do array da esquerda | preservadas |
| ... | comportamento semelhante ao array_merge() | reindexadas |
Como regra geral:
- Utilize
array_merge()quando desejar combinar arrays e permitir que valores posteriores sobrescrevam os anteriores. - Utilize
+quando estiver fornecendo valores padrão (defaults) que nunca devem sobrescrever valores existentes. - Utilize o operador de espalhamento (
...) quando a legibilidade for mais importante do que uma chamada explícita de função.
Mais adiante neste artigo também discutiremos o impacto dessas abordagens sobre o desempenho, principalmente quando arrays são combinados repetidamente dentro de laços.
9. Ordenando Arrays
Ordenar dados é uma das tarefas mais comuns em qualquer aplicação.
Seja exibindo produtos por preço, usuários por nome, artigos por data de publicação ou relatórios por faturamento, em algum momento você precisará ordenar um array.
O PHP fornece uma coleção bastante rica de funções de ordenação, cada uma voltada para um caso de uso específico.
Embora a quantidade de funções possa parecer confusa inicialmente, elas seguem uma lógica bastante consistente.
As duas perguntas mais importantes são:
- Você deseja ordenar pelas chaves ou pelos valores?
- As chaves originais precisam ser preservadas?
Depois de responder essas duas perguntas, escolher a função correta torna-se bastante simples.
Ordenando pelos Valores
A função mais simples é sort().
$numbers = [8, 3, 5, 1];
sort($numbers);
print_r($numbers);
Resultado:
[
1,
3,
5,
8,
]
sort() sempre ordena em ordem crescente.
Para ordenar em ordem decrescente, utilize rsort().
rsort($numbers);
Um detalhe importante é que ambas as funções descartam as chaves originais.
Preservando as Chaves
Quando estamos trabalhando com arrays associativos, perder as chaves normalmente não é desejável.
Nesses casos, o PHP oferece a função asort().
$scores = [
"Alice" => 90,
"Bob" => 75,
"Carol" => 95,
];
asort($scores);
Resultado:
[
"Bob" => 75,
"Alice" => 90,
"Carol" => 95,
]
Os valores foram ordenados, mas suas respectivas chaves permaneceram associadas.
A versão em ordem decrescente é arsort().
Ordenando pelas Chaves
Em algumas situações, os valores já estão na ordem desejada, mas você quer apenas ordenar as chaves.
$user = [
"email" => "...",
"age" => 30,
"country" => "...",
];
Utilizando ksort():
ksort($user);
Resultado:
[
"age" => 30,
"country" => "...",
"email" => "...",
]
A versão em ordem decrescente é krsort().
Ordenação Personalizada
Aplicações do mundo real normalmente exigem critérios de ordenação mais sofisticados.
Imagine que você queira ordenar pessoas pela idade.
$users = [
["name" => "John", "age" => 32],
["name" => "Alice", "age" => 25],
["name" => "Bob", "age" => 41],
];
É exatamente para isso que existe usort().
usort(
$users,
fn ($a, $b) => $a["age"] <=> $b["age"]
);
O operador nave espacial (spaceship operator) (<=>) retorna:
-1quando o valor da esquerda é menor;0quando ambos são iguais;1quando o valor da esquerda é maior.
Graças à sua simplicidade, tornou-se a forma preferida de implementar funções de comparação no PHP moderno.
Da mesma forma, podemos ordenar pelo nome.
usort(
$users,
fn ($a, $b) => strcmp($a["name"], $b["name"])
);
Qual função de ordenação utilizar?
A quantidade de funções disponíveis pode parecer intimidadora à primeira vista, mas a maioria das aplicações utiliza apenas algumas delas.
| Função | Ordena por | Preserva as chaves |
|---------|------------|--------------------|
| sort() | valores | ❌ |
| rsort() | valores (decrescente) | ❌ |
| asort() | valores | ✅ |
| arsort() | valores (decrescente) | ✅ |
| ksort() | chaves | ✅ |
| krsort() | chaves (decrescente) | ✅ |
| usort() | comparação personalizada | ❌ |
Mais adiante voltaremos ao tema de ordenação ao discutir desempenho e armadilhas comuns, incluindo ordenação por localização (locale-aware sorting), ordenação natural (natural sorting) e o custo de ordenar repetidamente grandes volumes de dados.
10. Pesquisando em Arrays
Encontrar informações dentro de um array é outra tarefa que você executará praticamente todos os dias.
O PHP oferece diversas funções para realizar buscas, cada uma otimizada para um objetivo específico.
Saber qual delas utilizar — e em quais situações — é importante não apenas para garantir a corretude do código, mas também para obter um bom desempenho.
As quatro funções que você encontrará com mais frequência são:
in_array();array_search();isset();array_key_exists().
Embora pareçam semelhantes, cada uma responde a uma pergunta completamente diferente.
in_array()
Utilize in_array() quando quiser saber se um determinado valor existe em um array.
$languages = [
"PHP",
"JavaScript",
"Go",
];
if (in_array("PHP", $languages)) {
echo "Found!";
}
Por padrão, a comparação não é estrita.
in_array("5", [5]);
O resultado será:
true
Para evitar conversões automáticas de tipos (type juggling), utilize comparações estritas.
in_array("5", [5], true);
Agora o resultado será:
false
Como regra geral, prefira sempre utilizar o terceiro parâmetro como true, a menos que você realmente queira uma comparação não estrita.
array_search()
Em algumas situações, saber apenas se um valor existe não é suficiente.
Você precisa descobrir em qual posição ele foi encontrado.
$index = array_search("Go", $languages, true);
Resultado:
2
Caso o valor não seja encontrado, a função retorna false.
Como 0 é um índice perfeitamente válido em um array, sempre utilize o operador de identidade (!==) para verificar o resultado.
if ($index !== false) {
// Encontrado
}
Nunca faça isto:
if ($index) {
...
}
Caso o elemento esteja na posição 0, a condição será avaliada como false, fazendo com que o código conclua incorretamente que o valor não foi encontrado.
Esse é um dos bugs mais antigos — e também um dos mais comuns — em aplicações PHP.
isset()
A função isset() verifica se uma chave existe e se o seu valor não é null.
$user = [
"name" => "John",
"email" => null,
];
isset($user["name"]);
Resultado:
true
Por outro lado:
isset($user["email"]);
retorna:
false
mesmo que a chave exista no array.
array_key_exists()
Se o objetivo é verificar apenas a existência da chave, independentemente do valor armazenado, utilize array_key_exists().
array_key_exists("email", $user);
Resultado:
true
Essa pequena diferença é responsável por uma quantidade surpreendente de bugs em sistemas de produção.
Veja a comparação:
| Situação | isset() | array_key_exists() |
|----------|:---------:|:--------------------:|
| A chave existe e contém "PHP" | ✅ | ✅ |
| A chave existe e contém 0 | ✅ | ✅ |
| A chave existe e contém false | ✅ | ✅ |
| A chave existe e contém null | ❌ | ✅ |
| A chave não existe | ❌ | ❌ |
Uma forma simples de memorizar essa diferença é:
isset()responde: "Posso utilizar esse valor com segurança?"array_key_exists()responde: "Essa chave existe?"
Considerações sobre Desempenho
Buscar por chave costuma ser significativamente mais rápido do que buscar por valor.
Funções como isset() e array_key_exists() aproveitam a tabela hash interna do PHP para localizar uma chave de forma extremamente eficiente.
Já in_array() e array_search() precisam percorrer os valores do array até encontrar uma correspondência — ou chegar ao final da coleção.
Na maioria das aplicações isso não faz diferença perceptível.
Entretanto, quando você trabalha com milhares ou milhões de elementos dentro de trechos críticos de desempenho, essa diferença pode se tornar bastante significativa.
Mais adiante veremos benchmarks e técnicas de otimização relacionadas a esse tema.
11. Desestruturação de Arrays (Array Destructuring)
Uma das adições mais elegantes do PHP moderno é a desestruturação de arrays (array destructuring).
Em vez de acessar cada elemento individualmente, ela permite extrair vários valores de um array em uma única instrução clara e expressiva.
Considere o seguinte array indexado:
$coordinates = [150, 75];
Sem utilizar desestruturação, escreveríamos:
$x = $coordinates[0];
$y = $coordinates[1];
Com desestruturação:
[$x, $y] = $coordinates;
O resultado é exatamente o mesmo, porém muito mais legível.
echo "X: {$x}, Y: {$y}";
Essa sintaxe é especialmente útil quando funções retornam múltiplos valores.
Imagine uma função que retorna uma data inicial e uma data final.
function getPeriod(): array
{
return [
'2025-01-01',
'2025-12-31',
];
}
[$start, $end] = getPeriod();
Em vez de acessar manualmente cada índice, os valores retornados são distribuídos diretamente entre as variáveis.
Ignorando Valores
Você não é obrigado a capturar todos os elementos do array.
Suponha que apenas o primeiro e o terceiro valores sejam relevantes.
$data = [
"John",
32,
"Canada",
];
Basta ignorar o elemento intermediário.
[$name, , $country] = $data;
Resultado:
$name => John
$country => Canada
Essa abordagem mantém o código limpo e evita variáveis temporárias desnecessárias.
Desestruturando Arrays Associativos
Desde o PHP 7.1, a desestruturação também funciona com arrays associativos.
$user = [
"id" => 15,
"name" => "John",
"email" => "john@example.com",
];
Em vez de escrever:
$id = $user["id"];
$name = $user["name"];
$email = $user["email"];
podemos fazer:
[
"id" => $id,
"name" => $name,
"email" => $email,
] = $user;
Observe que, diferentemente dos arrays indexados, a ordem não importa.
São as chaves que determinam qual valor será atribuído a cada variável.
Esse recurso é particularmente útil ao trabalhar com respostas de APIs, registros de banco de dados ou arrays de configuração quando apenas alguns campos são necessários.
Desestruturação dentro de um foreach
Uma das aplicações mais elegantes desse recurso ocorre dentro de laços de repetição.
Imagine que cada funcionário seja representado por um array indexado.
$employees = [
["Alice", "Developer"],
["Bob", "Designer"],
["Carol", "Manager"],
];
Em vez de acessar cada posição manualmente:
foreach ($employees as $employee) {
echo $employee[0];
echo $employee[1];
}
podemos desestruturar cada elemento automaticamente.
foreach ($employees as [$name, $role]) {
echo "{$name} - {$role}" . PHP_EOL;
}
O mesmo funciona com arrays associativos.
$users = [
[
"name" => "John",
"email" => "john@example.com",
],
[
"name" => "Alice",
"email" => "alice@example.com",
],
];
foreach ($users as [
"name" => $name,
"email" => $email,
]) {
echo "{$name}: {$email}" . PHP_EOL;
}
Esse estilo elimina acessos repetitivos por índice e torna o código significativamente mais legível.
Quando Utilizar Desestruturação?
A desestruturação brilha quando o array possui uma estrutura conhecida e previsível.
Alguns exemplos clássicos são:
- valores retornados por funções;
- linhas de arquivos CSV;
- registros de banco de dados;
- respostas de APIs;
- pares de coordenadas;
- intervalos de datas.
Por outro lado, ela perde parte da sua elegância quando aplicada a arrays contendo dezenas de campos ou muitas chaves opcionais.
Nesses casos, normalmente é mais claro atribuir apenas os valores realmente necessários.
Assim como diversos recursos do PHP moderno, a desestruturação não é algo que você utilizará em todo lugar. Porém, quando ela se encaixa no problema, torna o código muito mais limpo, expressivo e agradável de ler.
12. Operador de Espalhamento (Spread Operator)
O operador de espalhamento (...) tornou-se um dos recursos mais utilizados no PHP moderno.
Originalmente introduzido para desempacotar argumentos de funções, ele foi posteriormente estendido para arrays, oferecendo uma forma extremamente concisa e expressiva de construir novas coleções.
Conceitualmente, o operador de espalhamento expande um iterável em seus elementos individuais.
No contexto de arrays, é como se ele dissesse:
"Pegue todos os elementos deste array e insira-os exatamente aqui."
Criando Novos Arrays
Suponha que você possua dois arrays.
$backend = [
"PHP",
"MySQL",
];
$frontend = [
"JavaScript",
"CSS",
];
Em vez de utilizar array_merge(), você pode escrever:
$languages = [
...$backend,
...$frontend,
];
Resultado:
[
"PHP",
"MySQL",
"JavaScript",
"CSS",
]
Muitos desenvolvedores consideram essa sintaxe mais agradável porque ela se parece visualmente com o array que está sendo construído.
Misturando Valores Existentes e Novos
Uma das grandes vantagens do operador de espalhamento é permitir inserir novos elementos naturalmente durante a construção do array.
$languages = [
"HTML",
...$backend,
...$frontend,
"TypeScript",
];
Esse estilo costuma ser mais limpo do que utilizar diversas chamadas aninhadas de array_merge().
Espalhando Arrays Associativos
As versões modernas do PHP também permitem desempacotar arrays associativos.
$defaults = [
"host" => "localhost",
"port" => 3306,
];
$environment = [
"port" => 3307,
];
$config = [
...$defaults,
...$environment,
];
Resultado:
[
"host" => "localhost",
"port" => 3307,
]
Assim como acontece com array_merge(), valores posteriores sobrescrevem os anteriores.
Esse comportamento torna o operador de espalhamento extremamente útil para sobrescrever configurações padrão (configuration overrides).
Construindo Arrays Condicionalmente
Outro padrão bastante elegante consiste em adicionar elementos apenas quando uma determinada condição for satisfeita.
$user = [
"name" => "John",
...($isAdmin
? ["role" => "admin"]
: []),
];
Sem o operador de espalhamento, normalmente seria necessário criar o array e modificá-lo posteriormente com diversas instruções.
Esse padrão aparece com frequência em frameworks, serializadores de APIs, DTOs e builders.
Copiando Arrays
O operador de espalhamento também pode ser utilizado para criar uma cópia superficial (shallow copy) de um array.
$copy = [...$original];
Esse código é equivalente a:
$copy = array_merge([], $original);
Embora a otimização Copy-on-Write (CoW) do PHP torne desnecessária a criação explícita de cópias em muitos cenários, existem situações em que produzir um array independente melhora a legibilidade do código ou evita modificações acidentais.
Operador de Espalhamento vs array_merge()
Uma dúvida bastante comum é:
O operador de espalhamento substitui
array_merge()?
A resposta é:
Nem sempre.
Na maioria dos casos do dia a dia, ambos produzem exatamente o mesmo resultado.
$result = [
...$a,
...$b,
];
e
$result = array_merge($a, $b);
costumam ser completamente intercambiáveis.
A escolha normalmente depende apenas da legibilidade e do estilo adotado pela equipe.
Entretanto, array_merge() ainda apresenta vantagens quando é necessário combinar dinamicamente uma quantidade desconhecida de arrays.
$result = array_merge(...$arrays);
Da mesma forma, alguns desenvolvedores preferem a clareza de uma chamada de função em vez de um recurso da linguagem.
Nenhuma das abordagens é objetivamente melhor.
O importante é compreender que ambas realizam praticamente a mesma operação e escolher aquela que torna o código mais fácil de entender.
13. Desempenho
Desempenho é, provavelmente, um dos aspectos mais mal compreendidos dos arrays em PHP.
É muito fácil passar horas tentando otimizar pequenos trechos de código enquanto se ignoram operações que possuem um impacto muito maior no tempo de execução e no consumo de memória.
Antes de discutir funções específicas, vale estabelecer um princípio importante:
Primeiro escreva um código legível. Só depois pense em otimização — e apenas após medir o desempenho.
O PHP é extremamente otimizado internamente, e muitas crenças populares sobre desempenho simplesmente não resistem a um benchmark.
Ainda assim, compreender como os arrays funcionam ajuda a evitar diversas armadilhas comuns.
Arrays São Poderosos — Mas Não São Baratos
Como vimos anteriormente, os arrays do PHP são implementados como tabelas hash ordenadas (ordered hash tables).
Essa implementação oferece enorme flexibilidade, mas ela tem um custo.
Cada elemento armazena muito mais informações do que apenas seu valor, incluindo diversos metadados utilizados pela Zend Engine.
Para coleções pequenas ou médias, esse custo é praticamente irrelevante.
Entretanto, aplicações que manipulam centenas de milhares de registros devem estar cientes de que arrays do PHP consomem significativamente mais memória do que arrays de baixo nível presentes em linguagens como C ou Rust.
Felizmente, a maioria das aplicações web jamais chegará próxima desse limite.
foreach vs array_map()
Uma das discussões mais antigas da comunidade PHP é:
"
array_map()é mais rápido do queforeach?"
A resposta mais honesta é:
Na maioria das vezes, isso simplesmente não importa.
Ambos são implementados em C e altamente otimizados.
Mais importante ainda: eles resolvem problemas ligeiramente diferentes.
$result = [];
foreach ($numbers as $number) {
$result[] = $number * 2;
}
versus
$result = array_map(
fn ($number) => $number * 2,
$numbers
);
Na prática, a legibilidade deve ser o principal critério de escolha.
Se a operação representa naturalmente uma transformação, array_map() costuma comunicar melhor a intenção do código.
Se a lógica for mais complexa, um simples foreach normalmente será mais claro.
isset() vs in_array()
Outro equívoco bastante comum envolve desempenho de buscas.
Verificar se uma chave existe:
isset($users[$id]);
é uma operação completamente diferente de verificar se um valor existe:
in_array($id, $users, true);
A primeira operação aproveita a tabela hash interna do PHP para localizar a chave de forma extremamente eficiente.
A segunda precisa percorrer os valores até encontrar uma correspondência.
Caso sua aplicação realize buscas frequentes por identificadores, reorganizar os dados em um array associativo indexado pelo ID pode produzir ganhos de desempenho bastante significativos.
Em vez de:
$users = [
[
"id" => 15,
"name" => "John",
],
[
"id" => 42,
"name" => "Alice",
],
];
considere utilizar:
$users = [
15 => [
"name" => "John",
],
42 => [
"name" => "Alice",
],
];
Agora recuperar um usuário torna-se trivial.
$user = $users[42] ?? null;
Essa é uma otimização extremamente comum em sistemas de produção que manipulam grandes volumes de dados.
Evite array_merge() Dentro de Laços
Um dos erros de desempenho mais comuns entre iniciantes consiste em utilizar array_merge() repetidamente dentro de um loop.
$result = [];
foreach ($chunks as $chunk) {
$result = array_merge($result, $chunk);
}
A cada iteração, um novo array é criado contendo todos os elementos anteriores mais os novos elementos.
À medida que o array cresce, mais dados precisam ser copiados.
O custo de processamento e de alocação de memória aumenta rapidamente.
Sempre que possível, acumule os valores diretamente.
$result = [];
foreach ($chunks as $chunk) {
foreach ($chunk as $item) {
$result[] = $item;
}
}
Para grandes conjuntos de dados, essa abordagem costuma ser significativamente mais eficiente justamente por evitar cópias repetidas do array em crescimento.
Evite Cópias Desnecessárias
Graças ao mecanismo Copy-on-Write (CoW), muitos desenvolvedores acreditam, incorretamente, que toda atribuição de um array cria imediatamente uma cópia.
Não cria.
$a = $largeArray;
Essa instrução não aloca imediatamente uma nova área de memória.
Uma cópia real somente será criada quando uma das variáveis for modificada.
Essa otimização torna a passagem de arrays para funções muito mais barata do que muitos iniciantes imaginam.
Compreender esse comportamento ajuda a evitar otimizações prematuras baseadas em suposições incorretas.
O Maior Ganho de Desempenho
Curiosamente, o maior ganho de desempenho quase nunca vem da substituição de uma função por outra.
Ele vem da escolha da estrutura de dados correta.
Percorrer milhares de elementos repetidamente utilizando in_array() costuma ser muito mais lento do que organizar os dados em um array associativo e realizar buscas diretas por chave.
Da mesma forma, eliminar laços desnecessários geralmente produz ganhos muito maiores do que trocar foreach por alguma função considerada "mais elegante".
Em outras palavras, melhorias algorítmicas quase sempre produzem resultados muito superiores às micro-otimizações.
Esse é um princípio que vale não apenas para PHP, mas para engenharia de software como um todo.
14. Erros Comuns
Os arrays do PHP são extremamente flexíveis, mas essa mesma flexibilidade também facilita seu uso incorreto.
A maioria dos bugs envolvendo arrays em aplicações de produção não é causada por recursos obscuros da linguagem. Na prática, eles surgem devido a alguns erros bastante comuns — e surpreendentemente fáceis de cometer.
Conhecer essas armadilhas ajudará você a escrever um código mais previsível, mais fácil de manter e muito menos sujeito a bugs sutis.
Misturar Arrays Indexados e Associativos
O PHP permite que chaves numéricas e chaves do tipo string coexistam no mesmo array.
$data = [
"name" => "John",
0 => "PHP",
"country" => "Canada",
1 => "JavaScript",
];
Embora isso seja perfeitamente válido, normalmente indica que o array está tentando representar dois conceitos diferentes ao mesmo tempo.
Pergunte a si mesmo:
- Isto representa uma lista?
- Ou representa um objeto estruturado?
Tentar representar ambas as coisas simultaneamente geralmente prejudica a legibilidade do código.
Uma regra simples costuma funcionar muito bem:
- Listas devem possuir apenas índices numéricos sequenciais.
- Objetos, registros e estruturas de dados devem utilizar chaves descritivas.
Manter esses dois conceitos separados torna o código muito mais intuitivo.
Assumir que Índices Numéricos Sempre São Sequenciais
Muitos desenvolvedores acreditam que arrays indexados sempre possuem índices consecutivos.
Essa suposição deixa de ser verdadeira assim que um elemento é removido.
$languages = [
"PHP",
"JavaScript",
"Go",
];
unset($languages[1]);
print_r($languages);
Resultado:
[
0 => "PHP",
2 => "Go",
]
Observe que o índice 1 deixou de existir.
Se posteriormente seu código assumir que todos os índices entre 0 e count($array) - 1 estão presentes, cedo ou tarde surgirão comportamentos inesperados.
Caso índices consecutivos sejam realmente necessários, reindexe explicitamente o array.
$languages = array_values($languages);
Caso contrário, preserve as chaves originais.
Esquecer das Comparações Estritas
Funções como in_array() e array_search() utilizam comparações não estritas por padrão.
in_array("5", [5]);
Resultado:
true
Da mesma forma:
in_array(false, [0]);
também retorna:
true
Essas conversões automáticas de tipos (type juggling) já foram responsáveis por inúmeros bugs em sistemas de produção.
Sempre que possível, utilize comparações estritas.
in_array("5", [5], true);
Da mesma forma:
array_search($value, $array, true);
O terceiro parâmetro praticamente não impacta a legibilidade e deixa explícita a intenção do código.
Utilizar array_search() Incorretamente
Um erro clássico consiste em escrever:
if ($index = array_search("PHP", $languages)) {
...
}
Por que isso está errado?
Porque, se "PHP" estiver localizado na posição 0, a condição será avaliada como false.
A forma correta é:
if (($index = array_search("PHP", $languages, true)) !== false) {
...
}
Utilizar o operador de identidade (!==) evita uma das armadilhas mais antigas do PHP.
Modificar um Array Durante a Iteração
Alterar um array enquanto ele está sendo percorrido pode produzir resultados bastante confusos.
Por exemplo:
foreach ($numbers as $number) {
$numbers[] = $number;
}
Dependendo da situação, esse código pode gerar comportamentos inesperados e, em alguns casos, até mesmo um loop infinito.
Da mesma forma, remover elementos durante a iteração também exige bastante cuidado.
Sempre que possível, prefira construir um novo array ou utilizar array_filter() quando o objetivo for remover elementos.
Esquecer de Executar unset() em Referências
Referências são um recurso poderoso, mas também bastante fácil de utilizar incorretamente.
foreach ($numbers as &$number) {
$number *= 2;
}
Após o término do laço, $number continua apontando para o último elemento do array.
Se posteriormente você fizer:
$number = 100;
acabará modificando o array original sem perceber.
Sempre finalize referências explicitamente.
unset($number);
Essa pequena instrução evita uma categoria inteira de bugs extremamente difíceis de diagnosticar.
Usar Arrays para Tudo
Como arrays são extremamente convenientes, é comum vê-los sendo utilizados para absolutamente tudo.
Com o tempo, um simples array associativo acaba evoluindo para algo parecido com isto:
$user = [
"id" => 15,
"name" => "John",
"email" => "...",
"permissions" => [...],
"orders" => [...],
"settings" => [...],
"preferences" => [...],
...
];
Se um array passa a representar uma entidade rica de negócio, contendo validações, regras de negócio, comportamentos e invariantes, provavelmente chegou a hora de criar uma classe ou um Data Transfer Object (DTO).
Arrays são excelentes para transportar dados.
Objetos são excelentes para representar comportamento.
Saber identificar essa fronteira é uma habilidade importante de arquitetura de software.
15. Boas Práticas
Ao longo dos anos, a comunidade PHP consolidou diversas práticas que tornam o código mais limpo, mais seguro e muito mais fácil de manter.
Elas não são regras obrigatórias da linguagem, mas hábitos que valem a pena incorporar ao seu dia a dia.
Escolha a Estrutura de Dados Correta
Uma das decisões mais importantes acontece antes mesmo da primeira linha de código.
Pergunte-se:
Isto representa uma lista ou um objeto?
Se a ordem dos elementos é importante e todos representam o mesmo conceito, utilize um array indexado.
$languages = [
"PHP",
"JavaScript",
"Go",
];
Se cada valor possui um significado específico, utilize um array associativo.
$user = [
"name" => "John",
"email" => "john@example.com",
];
Tomar essa decisão logo no início melhora significativamente a legibilidade de toda a aplicação.
Utilize Chaves Descritivas
Compare:
$user[0];
$user[1];
$user[2];
com:
$user["name"];
$user["email"];
$user["country"];
A segunda versão praticamente se documenta sozinha.
Chaves descritivas reduzem a necessidade de comentários e facilitam enormemente a navegação pelo código.
Mantenha os Arrays Homogêneos
Embora o PHP permita misturar livremente diversos tipos de dados, consistência quase sempre produz código melhor.
Prefira:
$prices = [
10.5,
19.9,
49.0,
];
em vez de:
$data = [
10,
"John",
true,
null,
5.3,
];
Coleções homogêneas são mais fáceis de validar, transformar, documentar e compreender.
Prefira Comparações Estritas
Sempre que uma função oferecer suporte a comparações estritas, utilize-o, salvo quando houver um motivo muito específico para não fazê-lo.
in_array($id, $ids, true);
array_search($name, $names, true);
Evite depender das conversões automáticas de tipos do PHP.
Ser explícito quase sempre significa escrever um código mais seguro.
Escreva Código para Pessoas
Diversas funções de array permitem escrever código extremamente compacto.
Por outro lado, também é muito fácil transformar uma solução elegante em algo praticamente ilegível.
Considere este exemplo:
$result = array_reduce(
array_filter(
array_map(...),
),
...
);
Tecnicamente impressionante?
Talvez.
Fácil de entender daqui a seis meses?
Provavelmente não.
Muitas vezes dois simples foreach comunicam muito melhor a intenção do código.
Legibilidade deve sempre ter prioridade sobre esperteza.
Indexe Dados para Buscas Rápidas
Se sua aplicação procura registros por ID com frequência, evite percorrer o array inteiro repetidamente.
Em vez de:
foreach ($users as $user) {
if ($user["id"] === $id) {
...
}
}
construa um array associativo indexado pelo próprio identificador.
$usersById[$user["id"]] = $user;
Agora recuperar um usuário torna-se imediato.
$user = $usersById[$id] ?? null;
Esse padrão aparece constantemente em aplicações PHP de alto desempenho.
Aproveite a Biblioteca Padrão do PHP
A biblioteca padrão do PHP acumula décadas de evolução.
Funções como:
array_map();array_filter();array_reduce();array_column();array_count_values();array_flip();
frequentemente substituem dezenas de linhas de código personalizado.
Conhecê-las não apenas reduz a quantidade de código escrito, mas também produz soluções mais legíveis, mais confiáveis e mais alinhadas às práticas adotadas pela comunidade PHP.
Quanto melhor você conhecer a biblioteca padrão da linguagem, menos código precisará reinventar.
16. Exemplos Reais em Produção
Tudo o que vimos até aqui ganha muito mais valor quando aplicado a situações do mundo real.
Os exemplos a seguir representam padrões encontrados diariamente em aplicações PHP de produção.
Transformando Resultados de Banco de Dados
Imagine que uma consulta ao banco de dados retorne todos os usuários.
$users = [
[
"id" => 1,
"name" => "John",
],
[
"id" => 2,
"name" => "Alice",
],
];
Uma API REST talvez precise retornar apenas os nomes.
$names = array_column($users, "name");
Resultado:
[
"John",
"Alice",
]
Sem necessidade de escrever qualquer laço manualmente.
Indexando Registros pelo ID
Uma otimização extremamente comum consiste em transformar uma lista em uma tabela de consulta (lookup table).
Em vez de percorrer o array repetidamente:
foreach ($users as $user) {
if ($user["id"] === $id) {
...
}
}
crie um índice apenas uma vez.
$usersById = [];
foreach ($users as $user) {
$usersById[$user["id"]] = $user;
}
Agora qualquer busca torna-se imediata.
$user = $usersById[$id] ?? null;
Esse padrão aparece constantemente em ORMs, sistemas de autenticação, caches, gateways de API e inúmeras outras aplicações.
Filtrando Respostas de APIs
Imagine que um serviço externo retorne centenas de produtos.
A aplicação deve exibir apenas aqueles que estão ativos.
$activeProducts = array_filter(
$products,
fn ($product) => $product["active"]
);
O código comunica diretamente a regra de negócio, sem necessidade de estruturas condicionais complexas.
Preparando Respostas JSON
Suponha que um registro recuperado do banco contenha informações sensíveis.
$user = [
"id" => 15,
"name" => "John",
"email" => "...",
"password" => "...",
];
Antes de enviar a resposta para o cliente:
unset($user["password"]);
echo json_encode($user);
Arrays tornam extremamente simples reorganizar os dados antes de expô-los através de uma API.
Agrupando Registros
Imagine que seja necessário agrupar funcionários por departamento.
$result = [];
foreach ($employees as $employee) {
$result[$employee["department"]][] = $employee;
}
Resultado:
Engineering
Alice
Bob
Sales
Carol
David
Esse padrão aparece com enorme frequência em sistemas de relatórios, dashboards, indicadores e análises estatísticas.
Construindo Objetos de Configuração
Frameworks modernos normalmente constroem configurações a partir de múltiplas fontes.
$config = [
...$defaults,
...$environment,
...$userOverrides,
];
Cada camada sobrescreve a anterior, preservando os valores que não foram modificados.
Esse padrão pode ser encontrado em Laravel, Symfony, WordPress, Composer e praticamente qualquer projeto PHP moderno.
Processando Arquivos CSV
Outra situação em que arrays brilham é no processamento de arquivos CSV.
while (($row = fgetcsv($file)) !== false) {
[$id, $name, $email] = $row;
// Processa o registro...
}
A desestruturação torna o código muito mais legível do que acessar repetidamente índices numéricos.
Trabalhando com APIs JSON
A maioria das APIs REST acaba se transformando em arrays associativos logo após a desserialização.
$response = json_decode($json, true);
A partir desse momento, praticamente todas as técnicas apresentadas neste artigo passam a fazer sentido:
array_map()para transformar dados;array_filter()para remover registros desnecessários;array_column()para extrair campos específicos;array_reduce()para calcular agregações;array_merge()para combinar respostas;- desestruturação para simplificar o acesso a estruturas conhecidas.
Talvez essa seja a principal conclusão deste guia.
Arrays não são apenas mais um recurso da linguagem.
Eles constituem a base sobre a qual praticamente todas as aplicações PHP modernas são construídas.
Seja desenvolvendo APIs, processando arquivos, consumindo serviços externos, gerando relatórios ou implementando regras de negócio, dominar arrays permitirá escrever aplicações mais limpas, mais legíveis e mais eficientes.
17. Perguntas Frequentes (FAQ)
Os arrays do PHP preservam a ordem dos elementos?
Sim.
Diferentemente dos hash maps de muitas linguagens de programação, os arrays do PHP preservam a ordem em que os elementos foram inseridos.
$data = [];
$data["c"] = 1;
$data["a"] = 2;
$data["b"] = 3;
foreach ($data as $key => $value) {
echo $key . PHP_EOL;
}
Saída:
c
a
b
Essa previsibilidade é uma das razões pelas quais arrays funcionam tão bem para serialização em JSON, arquivos de configuração, respostas de APIs e geração de HTML.
Os arrays do PHP são tabelas hash?
Sim.
Internamente, o PHP implementa arrays como tabelas hash ordenadas (ordered hash tables).
Essa estrutura combina diversas características importantes:
- busca rápida por chaves;
- redimensionamento automático;
- suporte a chaves inteiras e strings;
- preservação da ordem de inserção.
A desvantagem é o maior consumo de memória quando comparado a arrays de baixo nível encontrados em linguagens como C.
Na prática, essa troca compensa amplamente para aplicações web, nas quais produtividade costuma ser muito mais importante do que economizar alguns bytes de memória.
Qual é a diferença entre arrays indexados e arrays associativos?
Tecnicamente, nenhuma.
Ambos utilizam exatamente a mesma estrutura de dados interna.
A única diferença está no tipo das chaves.
Arrays indexados utilizam, predominantemente, índices inteiros.
$languages = [
"PHP",
"JavaScript",
];
Já arrays associativos utilizam chaves descritivas.
$user = [
"name" => "John",
"email" => "john@example.com",
];
Conceitualmente:
- arrays indexados representam listas;
- arrays associativos representam registros, objetos ou dicionários.
array_map() é mais rápido que foreach?
Na maioria das situações, essa não é a pergunta correta.
Ambos são altamente otimizados.
A pergunta mais importante é:
Qual das duas abordagens torna o código mais fácil de entender?
Utilize array_map() quando cada elemento deve ser transformado em outro elemento.
Utilize foreach quando a lógica é mais procedural, envolve efeitos colaterais ou exige um processamento mais complexo.
Na prática, a diferença de legibilidade quase sempre é muito mais importante do que qualquer diferença de desempenho.
Quando devo utilizar array_reduce()?
array_reduce() é indicado sempre que vários elementos precisam produzir um único resultado.
Alguns exemplos:
- calcular somatórios;
- calcular médias;
- construir índices associativos;
- agrupar registros;
- gerar relatórios;
- acumular estatísticas.
Caso a lógica de redução fique difícil de compreender, não hesite em substituí-la por um foreach bem escrito.
Código claro quase sempre é melhor do que código excessivamente sofisticado.
Por que array_filter() remove 0 e strings vazias?
Quando nenhum callback é informado, array_filter() remove todos os valores considerados falsy pelo PHP.
Por exemplo:
$data = [
0,
false,
"",
null,
"PHP",
];
$result = array_filter($data);
Resultado:
[
"PHP",
]
Se sua intenção for remover apenas valores null — ou aplicar qualquer outro critério específico — forneça explicitamente uma função de callback.
$result = array_filter(
$data,
fn ($value) => $value !== null
);
Ser explícito evita diversos bugs sutis.
Qual a diferença entre isset() e array_key_exists()?
Essa é uma das dúvidas mais frequentes entre desenvolvedores PHP.
isset() verifica se a chave existe e se seu valor não é null.
isset($user["email"]);
Já array_key_exists() verifica apenas se a chave existe.
array_key_exists("email", $user);
Se null for um valor válido para sua aplicação, normalmente array_key_exists() é a escolha correta.
Atribuir um array para outra variável cria uma cópia?
Não imediatamente.
O PHP utiliza Copy-on-Write (CoW).
$a = [1, 2, 3];
$b = $a;
Nesse momento, ambas as variáveis compartilham a mesma estrutura interna.
Uma cópia real somente será criada quando uma delas sofrer alguma modificação.
$b[] = 4;
Essa otimização torna a passagem de arrays entre funções muito mais eficiente do que muitos desenvolvedores imaginam.
Por que arrays do PHP consomem tanta memória?
Cada elemento de um array armazena muito mais do que apenas seu valor.
Internamente, o PHP mantém metadados relacionados a:
- hashing;
- contagem de referências;
- informações de tipo;
- ordem de inserção;
- gerenciamento de memória.
Esses metadados tornam os arrays extremamente flexíveis, mas também fazem com que eles sejam significativamente mais pesados do que arrays primitivos de linguagens de baixo nível.
Devo utilizar arrays ou objetos?
Depende do que você está modelando.
Como regra prática:
Utilize arrays quando estiver trabalhando com dados.
Por exemplo:
- respostas JSON;
- arquivos de configuração;
- linhas de CSV;
- payloads de APIs;
- transformações temporárias.
Utilize objetos quando estiver modelando comportamentos.
Se um array começa a exigir validações, regras de negócio, invariantes ou dezenas de campos relacionados, provavelmente chegou o momento de criar uma classe específica.
Essa distinção costuma produzir um código muito mais organizado, reutilizável e fácil de manter.
Conclusão
Sem exagero, os arrays são um dos recursos mais importantes de toda a linguagem PHP.
Eles estão em todos os lugares: requisições HTTP, resultados de consultas ao banco de dados, documentos JSON, arquivos de configuração, componentes internos de frameworks, bibliotecas de terceiros e praticamente qualquer aplicação PHP que você venha a desenvolver.
Mesmo que você não perceba, grande parte do ecossistema PHP gira em torno deles.
Entretanto, dominar arrays vai muito além de saber criar um [] ou percorrê-los utilizando foreach.
Ao longo deste guia vimos que compreender como os arrays funcionam internamente ajuda a explicar por que determinadas operações são extremamente rápidas, por que outras são relativamente custosas e por que detalhes aparentemente pequenos — como preservar chaves ou utilizar comparações estritas — podem ter um impacto significativo na corretude, na legibilidade e na manutenção do código.
Também exploramos a rica biblioteca de funções disponibilizada pelo PHP.
Funções como array_map(), array_filter(), array_reduce(), array_column(), array_merge() e muitas outras permitem expressar transformações complexas de dados com um código normalmente mais curto, mais declarativo e menos propenso a erros do que implementações baseadas em laços aninhados.
Tão importante quanto conhecer essas funções é saber quando não utilizá-las.
Código limpo não significa substituir todo foreach por uma chamada a array_map() ou criar cadeias enormes de funções apenas porque a linguagem permite.
O objetivo deve ser sempre comunicar a intenção do código da forma mais clara possível.
Se existe uma única ideia que vale a pena levar deste artigo, é esta:
Um excelente desenvolvedor PHP não conhece apenas as funções de array. Ele sabe quando utilizá-las, por que utilizá-las e, principalmente, quando não utilizá-las.
Esse discernimento nasce da compreensão dos conceitos por trás da linguagem, e não da simples memorização da biblioteca padrão.
A boa notícia é que praticamente tudo o que você aprendeu aqui vai muito além do PHP.
Mapear (mapping), filtrar (filtering), reduzir (reducing), ordenar (sorting), agrupar (grouping), indexar (indexing) e transformar coleções são conceitos presentes em praticamente todas as linguagens modernas.
Ao dominar essas técnicas em PHP, você também evolui como desenvolvedor de software de maneira geral.
Este artigo teve como objetivo construir uma base sólida sobre arrays.
Entretanto, diversos assuntos apresentados aqui merecem um aprofundamento próprio e serão explorados em artigos dedicados, entre eles:
- Um guia completo sobre
array_map(); - Dominando
array_filter(); - Entendendo
array_reduce(); - Como ordenar arrays de forma eficiente em PHP;
- Técnicas avançadas para pesquisar dados em arrays;
- Benchmarks e desempenho de arrays em PHP;
- Entendendo o funcionamento do Copy-on-Write (CoW);
- Arrays associativos versus objetos: quando utilizar cada um;
- Técnicas avançadas de manipulação de arrays.
Se este guia foi útil para você, considere adicioná-lo aos favoritos e compartilhá-lo com outros desenvolvedores PHP.
Arrays estão entre os recursos mais utilizados da linguagem, mas também entre os menos compreendidos em profundidade. Investir algum tempo para dominá-los é uma daquelas habilidades que continuam gerando retorno ao longo de toda a carreira.
Quanto melhor você compreender arrays, melhor será o código que escreverá — mais legível, mais expressivo, mais eficiente e muito mais fácil de manter.