PHP array delete by value (not key): uma análise aprofundada
\n\nImagine: você está escrevendo um script em PHP, processando uma lista de produtos, e de repente precisa remover do array um item com um preço ou nome específico. Você sabe exatamente o valor — por exemplo, "maçã" — mas não faz ideia de qual índice ele ocupa. Situação familiar? Se sim, você não está sozinho: a pergunta "PHP array delete by value (not key)" acumula milhares de visualizações no Stack Overflow. E não é por acaso.
No PHP, não existe uma função nativa array_remove_by_value(). Por isso, os desenvolvedores dão seus jeitos: alguns escrevem um loop, outros usam array_search em conjunto com unset, e ainda há quem prefira array_diff ou array_filter. Mas o que acontece internamente? Qual método é mais rápido? E por que o mesmo código pode se comportar de forma diferente em versões distintas do PHP?
Neste artigo, não vamos apenas fornecer uma solução pronta — vamos explorar os bastidores de cada abordagem, analisar sua performance e destacar as armadilhas. Além disso, mostraremos um caso real da vida de um desenvolvedor backend. Vamos nessa!
\n\nO método clássico: array_search + unset
\n\nA resposta mais popular no Stack Overflow é esta:
\n\n<?php\n$array = ['maçã', 'pera', 'laranja', 'pera'];\n$value = 'pera';\n\nif (($key = array_search($value, $array)) !== false) {\n unset($array[$key]);\n}\n?>\n\nEste código encontra a primeira ocorrência do valor e a remove. Mas vamos entender o que realmente acontece aqui.
\n\nComo o array_search funciona
\n\narray_search() realiza uma busca linear. O PHP percorre o array do início ao fim, comparando cada valor com o valor procurado. A comparação padrão é não estrita (==), ou seja, 1 e '1' são considerados iguais. Se você precisar de uma comparação estrita (===), passe o terceiro parâmetro true:
<?php\n$array = [0, '0', 1];\n$key = array_search('0', $array, true); // retorna 1 (string '0'), não 0\n?>\n\nSe o valor não for encontrado, a função retorna false. Por isso, a verificação !== false é obrigatória — caso contrário, unset($array[0]) removeria o primeiro elemento se o valor estivesse na chave 0.
A armadilha: unset não reindexa o array
\n\nApós o unset, o array permanece associativo — as chaves numéricas não são reorganizadas. Se você precisar de um array denso com índices sequenciais, use array_values():
<?php\n$array = ['maçã', 'pera', 'laranja'];\nunset($array[1]);\n$array = array_values($array); // ['maçã', 'laranja'] com chaves 0 e 1\n?>\n\nMas lembre-se: array_values() cria um novo array, o que aumenta o consumo de memória.
Removendo todas as ocorrências: array_diff
\n\nSe você precisa remover todas as ocorrências de um valor, usar array_search em um loop não é a melhor ideia. Uma solução muito mais elegante é o array_diff():
<?php\n$array = ['maçã', 'pera', 'laranja', 'pera'];\n$array = array_diff($array, ['pera']);\n// Resultado: ['maçã', 'laranja'] (as chaves são preservadas)\n?>\n\nA função retorna um novo array, do qual todos os elementos que coincidem com os valores do segundo array são removidos. Internamente, o PHP usa uma tabela hash para o segundo array, tornando a operação O(n + m), onde n é o tamanho do primeiro array e m é o tamanho do segundo.
\n\nImportante: array_diff compara os valores como strings ((string) $elem1 === (string) $elem2). Para tipos mistos, isso pode gerar resultados inesperados:
<?php\n$array = [0, '0', false];\n$result = array_diff($array, [0]);\n// Resultado: