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!== falsegeprüft. - Das
!== falseist zwingend, sonst scheitert der Code am ersten Element. - Dritten Parameter von
array_search()auftruesetzen — sonst trifft eine Suche nach0auch einnull. - Alle Vorkommen:
array_filter()mit!==oderarray_diff(). array_diff()vergleicht als String; beinull,falseoder gemischten Typen lieberarray_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, ...).