8 Stimmen

Entfernen eines Elements aus einem Objekt in einer Schleife

Ich habe eine Reihe von Db-Ergebnissen, die in einem Objekt gespeichert sind. Ich muss durch die Ergebnisse iterieren und eine Eigenschaft überprüfen (unter Verwendung einer anderen DB-Abfrage) und dann eine Bedingungsanweisung verwenden, um das Element aus dem Objekt zu entfernen. Hier ist eine vereinfachte Version dessen, was ich versuche:

foreach ($products as $product) {

    if(!$product->active) {
        unset($product);
    }

}
print_r($products);

Wenn ich jedoch print_r ausführe, sind die Elemente immer noch im Objekt. Ich bin verwirrt.

21voto

realshadow Punkte 2589

Das ist zu erwartendes Verhalten. Es gibt zwei Hauptwege, um das zu tun, was du möchtest

foreach ($products as $key => $product) {

    if(!$product->active) {
        unset($products[$key]);
    }

}

Der zweite Weg wäre, Referenzen zu verwenden

foreach ($products as &$product) {

    if(!$product->active) {
        unset($product);
    }

}

4voto

Mathieu Dumoulin Punkte 11968

Sie müssen verstehen, dass das Entfernen eines Objekts in PHP keine Auswirkungen hat. Lassen Sie mich zunächst ein wichtiges Detail mit FOREACH erklären:

Wenn Sie Folgendes tun:

$a = array(1,2,3,4,5);
foreach($a as $b){
    unset($b);
}

Wird $a zuerst im Speicher kopiert. Es handelt sich nicht um eine brutale Kopie per se, es kopiert nur eine Referenz auf die Daten und erhöht die Anzahl der Verwendungen des Arrays (1,2,3,4,5) im Speicher. Innerhalb von $b haben Sie Kopien der Daten, die in $a gefunden wurden. Daher bedeutet das Löschen aus dem Speicher nur, dass Sie sagen: Entferne $b aus der Kopie von $a. Daher wird keinerlei Änderung am echten $a vorgenommen.

Wenn Sie Folgendes tun würden:

$a = array(1,2,3,4,5);
foreach($a as $key => $b){
    unset($a[$key]);
}

Dann hätten Sie hier eine Kopie von $a im Speicher. Das Foreach würde auf dieser Kopie iterieren und Ihnen Schlüssel für jedes Element von $a bereitstellen, das in $b kopiert wird. Wenn Sie unset($a[$key]) aufrufen, teilen Sie PHP mit, das Array in $a zu beeinflussen, das kopiert wurde, als die foreach-Schleife begann. Aber jetzt, anstatt die Kopie zu beeinflussen, verwenden Sie den $key, um auf ein Element in $a zu verweisen, das tatsächlich im Speicher existiert und auf das Sie zugreifen können.

Jetzt zum zweiten Teil, wenn wir uns Objekte ansehen... Das Entfernen eines Objekts hat keine Auswirkung, weil Variablen, die Objekte enthalten, nur Verweise auf Daten im Speicher mit einer Zählung sind. Wenn Sie also $a = new Object() setzen und dann $b = $a, erstellen Sie einen neuen Verweis auf dieses Objekt, ohne es zu kopieren.

Wenn Sie unset($a) aufrufen, entfernen Sie nur den Verweis auf das Objekt und $b würde immer noch auf dieses Objekt im Speicher verweisen. Wenn Sie unset($b) aufrufen, entfernen Sie dann den Objektverweis aus dem Speicher, weil nichts darauf zeigt.

Hoffentlich wird das für Sie verständlicher...

Viel Glück

1voto

Alon Eitan Punkte 11902

Versuchen Sie das:

// $id ist der Schlüssel, $product ist der Wert
foreach ($products as $id => $product) {
    if(!$product->active) {
        unset($products[$id]);
    }
}

1voto

Jon Punkte 411383

Sie können die Variable selbst nicht aufheben. Sie müssen die foreach-Syntax verwenden, die Ihnen auch den Schlüssel des Elements liefert, und diesen verwenden, um den Schlüssel im Array aufzuheben:

foreach ($products as $key => $product) {
    if(!$product->active) {
        unset($products[$key]);
    }
}

1voto

Aurelio De Rosa Punkte 21158

Verwenden Sie stattdessen diese Zeile:

foreach ($products as &$product)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X