Para remover um elemento de um array PHP pela chave, use unset($array[$key]). O elemento some, as outras chaves continuam exatamente como estavam, e aplicar unset numa chave que não existe não é erro.
Olhe o segundo resultado: as chaves agora são 0, 2, 3. O unset nunca renumera.
Reindexar o array depois do unset
Uma lista com buraco nas chaves causa problemas depois: um loop for ($i = 0; ...) encontra o índice ausente, e o json_encode escreve um objeto JSON em vez de um array. O array_values() devolve chaves limpas.
Remover pela posição com array_splice
array_splice($array, $offset, $length) remove $length elementos a partir da posição $offset, renumera as chaves e retorna o que removeu. Um offset negativo conta a partir do fim. Ele também pode inserir elementos de substituição na mesma chamada.
O array_splice trabalha com posições, não com chaves: num array associativo ele remove pelo lugar na ordem e mantém as chaves string. A página sobre array_slice o compara com o array_slice, que copia uma parte sem alterar o original.
Remover um elemento pelo valor
array_diff($array, [$value]) retorna o array sem todos os elementos iguais a $value, mantendo as chaves do resto. Para remover só a primeira correspondência, encontre a chave com array_search e aplique unset.
O array_diff compara valores como strings, então array_diff([1, "1", 2], [1]) remove tanto o inteiro quanto a string. Quando a condição é mais que "igual a este valor", use o array_filter com um callback.
Remover o primeiro ou o último elemento
array_shift() remove o primeiro elemento e array_pop() remove o último. Os dois retornam o elemento removido, o que os torna práticos para filas e pilhas.
O array_shift renumera as chaves numéricas a partir de 0. O array_pop não precisa, já que o buraco fica no fim.
Remover várias chaves de uma vez
O unset aceita vários elementos numa chamada. Para remover uma lista de chaves que está num array, inverta-a com array_flip() para que os nomes virem chaves, e passe-a para o array_diff_key().
Erro comum: unset com array_search quando o valor não existe
O array_search retorna false quando não encontra nada, e false usado como chave de array vira 0. Então esta linha apaga o primeiro elemento sempre que o valor não está no array:
Sempre guarde o resultado do array_search e compare com !== false antes de usá-lo como chave. Um simples if ($key) também não basta: uma correspondência no índice 0 também é falsa.
Perguntas frequentes
Como removo um elemento de um array pelo valor no PHP?
Para remover todas as ocorrências, use array_diff($arr, ['value']). Para remover só a primeira, encontre a chave e aplique unset, verificando se ela foi encontrada: $k = array_search('value', $arr); if ($k !== false) { unset($arr[$k]); }.
Como reindexo um array depois do unset?
Envolva em array_values(): $arr = array_values($arr); renumera as chaves a partir de 0. Outra opção é remover o elemento com array_splice($arr, $index, 1), que renumera para você.
Como removo o primeiro ou o último elemento de um array?
array_shift($arr) remove e retorna o primeiro elemento e renumera as chaves numéricas. array_pop($arr) remove e retorna o último elemento.
Posso aplicar unset num elemento dentro de um foreach?
Sim. foreach ($arr as $k => $v) { if ($v < 0) { unset($arr[$k]); } } é seguro, porque o foreach percorre uma cópia do array enquanto você altera o original. As chaves ficam com buracos, então chame array_values() depois se precisar de uma lista.
unset numa chave que não existe causa erro?
Não. unset($arr['missing']) não faz nada e não gera aviso, então você não precisa verificar com isset antes.