PHP: Wie löscht man ein Array-Element über seinen Wert?

unset($array[$schluessel]) setzt voraus, dass du den Schlüssel kennst. Oft kennst du aber nur den Wert. Dann musst du erst den Schlüssel suchen — und dabei gibt es eine Zeile, die man leicht falsch schreibt.

Ein Vorkommen entfernen

<?php
  $schluessel = array_search('gruen', $farben, true);
  if ($schluessel !== false) {
    unset($farben[$schluessel]);
  }
?>

array_search() liefert den Schlüssel des ersten Treffers, oder false, wenn der Wert nicht vorkommt.

Wie in Artikel 0005 beschrieben hinterlässt unset() eine Lücke in den Schlüsseln:

array_search('gruen', $a, true) : 1
danach : ["rot","blau"]  keys=[0,2]

Wenn du fortlaufende Schlüssel brauchst — etwa weil das Array als JSON-Array herausgehen soll — hängst du ein array_values() an.

Die Zeile, die man falsch schreibt

Das !== false ist nicht Zierde. Schreibt man stattdessen einfach if ($schluessel), dann funktioniert der Code für alle Elemente außer dem ersten:

Index von 'rot'   : 0
if ($i)           : false   <- der Treffer wird übersehen!
if ($i !== false) : true

array_search() liefert für das erste Element den Schlüssel 0, und 0 ist falsy. Das Element wird gefunden und trotzdem nicht gelöscht. Ein Fehler, den man in Tests gerne übersieht, weil man selten mit dem ersten Element testet.

Dasselbe gilt übrigens für assoziative Arrays mit einem Schlüssel wie '0' — den macht PHP intern zu einem Integer.

Der dritte Parameter

Der dritte Parameter von array_search() schaltet auf strikten Vergleich. Ohne ihn vergleicht PHP lose, und dann findet die Suche Dinge, die du nicht gemeint hast:

array_search('1', [1,2,3])        : 0       <- der String trifft den Integer
array_search('1', [1,2,3], true)  : false
array_search(0, [null,'x'])       : 0       <- null == 0
array_search(0, [null,'x'], true) : false

Der zweite Fall ist der unangenehme. Du suchst nach der Zahl 0 und löschst ein null. Bei Daten aus einer Datenbank, in denen null regelmäßig vorkommt, ist das ein Fehler, der lange unbemerkt bleibt.

Meine Empfehlung: den dritten Parameter immer auf true setzen. Wenn du wirklich lose vergleichen willst, schreib einen Kommentar dazu.

Alle Vorkommen entfernen

array_search() findet nur den ersten Treffer. Kommt der Wert mehrfach vor, brauchst du etwas anderes.

array_filter() mit einer eigenen Bedingung:

<?php
  $ohneA = array_filter($werte, fn($v) => $v !== 'a');
?>
array_filter : ["b","c"]  keys=[1,3]

array_diff() ist kürzer und kann mehrere Werte auf einmal:

<?php
  $ohneA  = array_diff($werte, ['a']);
  $ohneAC = array_diff($werte, ['a', 'c']);
?>
array_diff($e, ['a'])   : ["b","c"]  keys=[1,3]
mehrere auf einmal      : ["b"]

Beide erhalten die Schlüssel, beide hinterlassen also Lücken.

Warum ich array_diff() nicht überall empfehle

array_diff() hat eine Eigenschaft, die man kennen muss: Sie vergleicht die Werte als String. Das Handbuch sagt das auch, nur liest man dort selten nach.

array_diff([0,1,2,'0'], [false]) : [0,1,2,"0"]   <- nichts entfernt
array_diff([0,1,2], ['0'])       : [1,2]         <- die 0 ist weg

In der ersten Zeile wird false zu '', und das ist keines der Elemente — also passiert nichts. In der zweiten Zeile wird '0' zu '0' und trifft damit die Integer-0.

Sobald null, false oder gemischte Typen im Array stehen, ist array_diff() also die falsche Wahl. array_filter() mit !== vergleicht strikt und macht genau das, was dasteht. Bei reinen String-Arrays — Tags, Namen, IDs als Text — kannst du array_diff() bedenkenlos nehmen.

Assoziative Arrays

Bei einem assoziativen Array willst du array_values() gerade nicht, weil es dir die Schlüssel zerstört:

<?php
  $ohneEins = array_filter($konfig, fn($v) => $v !== 1);
?>
array_filter : {"b":2}

Die Schlüssel bleiben erhalten, und das ist hier genau richtig.

Zusammenfassung

  • Ein Vorkommen: array_search() + unset(), mit !== false geprüft.
  • Das !== false ist zwingend, sonst scheitert der Code am ersten Element.
  • Dritten Parameter von array_search() auf true setzen — sonst trifft eine Suche nach 0 auch ein null.
  • Alle Vorkommen: array_filter() mit !== oder array_diff().
  • array_diff() vergleicht als String; bei null, false oder gemischten Typen lieber array_filter().
  • array_values() nur bei Listen, nicht bei assoziativen Arrays.

Hinweis zu Netcup (Werbung)

Der deutsche Hoster Netcup bietet unter anderem günstige und zugleich leistungsstarke Webhosting Pakete, KVM-basierte Root Server und dezidierte Server an. Mit unseren Gutscheincodes kannst du noch mehr Geld sparen (6€ bei deiner ersten Bestellung, 30% Rabatt auf alle KVM-basierten Root Server, ...).