Regel
Array-Filterergebnisse mit array_values() umschließen
Funktionen wie array_filter() behalten die ursprünglichen Schlüssel bei,
was zu Fehlern führen kann, wenn der Code sequentielle
numerische Indizes ab 0 erwartet.
Unterstützte Sprachen: PHPEinleitung
PHPs array_filter() bewahrt die ursprünglichen Array-Schlüssel beim Filtern von Elementen, selbst bei numerisch indizierten Arrays. Nach dem Filtern [0 => 'a', 1 => 'b', 2 => 'c'] um Index 1 zu entfernen, erhalten Sie [0 => 'a', 2 => 'c'] mit einer Lücke in den numerischen Schlüsseln. Code, der sequentielle Indizes ab 0 erwartet, bricht beim Zugriff ab $array[1] oder iterieren mit Annahmen über fortlaufende Indizes. Dieses Verhalten überrascht Entwickelnde, die aus anderen Sprachen kommen, in denen das Filtern neu indizierte Arrays zurückgibt.
Warum es wichtig ist
Code-Wartbarkeit: Nicht-sequentielle Array-Schlüssel erzeugen subtile Fehler, die nur unter bestimmten Bedingungen auftreten. Code, der mit ungefilterten Arrays einwandfrei funktioniert, schlägt nach dem Filtern mysteriöserweise fehl, wenn er davon ausgeht count($array) - 1 ist der höchste gültige Index. Das Debuggen dieser Probleme verschwendet Zeit, da die Grundursache nicht offensichtlich ist: Sie sehen ein Array mit drei Elementen, können aber nicht auf das zweite mit Index 1 zugreifen.
JSON-Kodierungsprobleme: Wenn Sie json_encode() ein Array mit nicht-sequenziellen Schlüsseln, behandelt PHP es als Objekt statt als Array, was zu folgendem Ergebnis führt: {"0":"a","2":"c"} anstatt ["a","c"]. Frontend-Code, der JSON-Arrays erwartet, erhält stattdessen Objekte, wodurch Iteration und Array-Methoden fehlschlagen. Diese Diskrepanz zwischen PHP-Arrays und JavaScript-Arrays verursacht Integrationsfehler, die erst nach Filteroperationen auftreten.
Iterations- und Paginierungsfehler: Code, der Ergebnisse paginiert oder Arrays in Blöcke aufteilt, bricht, wenn Schlüssel nicht sequenziell sind. Schleifen von 0 bis count($array) greift auf undefinierte Indizes zu. Verwendung von array_slice() für die Paginierung führt zu unerwarteten Ergebnissen, da sie auf Positionen operiert, aber ursprüngliche Schlüssel zurückgibt. Diese Fehler häufen sich in komplexen Datenverarbeitungspipelines.
Code-Beispiele
❌ Nicht konform:
function getActiveUsers(array $users): array {
$activeUsers = array_filter($users, function($user) {
return $user['status'] === 'active';
});
// Bug: assumes index 0 exists and keys are sequential
$firstActive = $activeUsers[0] ?? null;
// Bug: JSON encodes as object if keys aren't sequential
return json_encode($activeUsers);
}
$users = [
['id' => 1, 'status' => 'inactive'],
['id' => 2, 'status' => 'active'],
['id' => 3, 'status' => 'active']
];
// Returns {"1":{"id":2...},"2":{"id":3...}} (object, not array)
getActiveUsers($users);
Warum es falsch ist: Nachdem das Filtern den Index 0 entfernt hat, hat das Array die Schlüssel [1, 2] anstatt [0, 1], wodurch $activeUsers[0] undefined. Die JSON-Kodierung erzeugt ein Objekt anstelle eines Arrays, da die Schlüssel nicht sequenziell sind, was Frontend-Code, der Arrays erwartet, beschädigt.
✅ Konform:
function getActiveUsers(array $users): string {
$activeUsers = array_filter($users, function($user) {
return $user['status'] === 'active';
});
// Reindex to sequential keys starting from 0
$activeUsers = array_values($activeUsers);
// Now index 0 always exists for non-empty arrays
$firstActive = $activeUsers[0] ?? null;
// JSON encodes as proper array: [{"id":2...},{"id":3...}]
return json_encode($activeUsers);
}
$users = [
['id' => 1, 'status' => 'inactive'],
['id' => 2, 'status' => 'active'],
['id' => 3, 'status' => 'active']
];
// Returns [{"id":2...},{"id":3...}] (array, as expected)
getActiveUsers($users);
Warum dies wichtig ist: array_values() indiziert das gefilterte Array neu, um sequenzielle numerische Schlüssel ab 0 zu erhalten, was den Indexzugriff vorhersehbar macht und sicherstellt, dass die JSON-Kodierung Arrays anstelle von Objekten erzeugt. Die Funktion verhält sich wie erwartet, unabhängig davon, welche Elemente herausgefiltert wurden.
Fazit
Immer umhüllen array_filter(), array_diff(), und ähnliche Funktionen mit array_values() wenn Sie sequentielle numerische Indizes benötigen. Dies verhindert subtile Fehler durch nicht-sequentielle Schlüssel und stellt sicher, dass die JSON-Kodierung Arrays anstelle von Objekten erzeugt. Die Leistungskosten sind im Vergleich zur eingesparten Debugging-Zeit vernachlässigbar.
.avif)
