Seltsames Verhalten von foreach

Lesezeit: 3 Minuten

Seltsames Verhalten von foreach
Manisch Trivedi

<?php
  $a = array('a', 'b', 'c', 'd');

  foreach ($a as &$v) { }
  foreach ($a as $v) { }

  print_r($a);
?>

Ich denke, es ist ein normales Programm, aber dies ist die Ausgabe, die ich bekomme:

Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => c
)

Kann mir das bitte jemand erklären?

  • Was macht “Ich denke, es ist ein normales Prog, aber ich habe das Web gesehen………dann ….ahh, was ist das?” bedeuten?

    – Bart Kiers

    11. Februar 2011 um 13:01 Uhr

  • @Bart Kiers: Er scheint benommen zu sein.

    – BoltClock

    11. Februar 2011 um 13:04 Uhr

  • mögliches Duplikat von Unbeabsichtigte Zerstörung des PHP-Array-Elements?

    – alexn

    11. Februar 2011 um 13:25 Uhr

  • Dies ist die beste Erklärung für dieses Verhalten: schlueters.de/blog/archives/141-References-and-foreach.html

    – Stefan Gehrig

    11. Februar 2011 um 13:26 Uhr

  • Mögliches Duplikat von Seltsames Verhalten nach Schleife durch Referenz – Ist dies ein PHP-Fehler?

    – John Carter

    5. Mai 2012 um 11:09 Uhr

Seltsames Verhalten von foreach
Markus Bäcker

Dies ist ein gut dokumentiertes PHP-Verhalten Warnung auf der foreach-Seite von php.net

Warnung

Referenz von a $Wert und das letzte Array-Element bleiben auch nach dem für jeden Schleife. Es wird empfohlen, es durch unset() zu zerstören.

$a = array('a', 'b', 'c', 'd');

foreach ($a as &$v) { }
unset($v);
foreach ($a as $v) { }

print_r($a);

BEARBEITEN

Versuchen Sie eine Schritt-für-Schritt-Anleitung für das, was hier tatsächlich passiert

$a = array('a', 'b', 'c', 'd');
foreach ($a as &$v) { }   // 1st iteration $v is a reference to $a[0] ('a')
foreach ($a as &$v) { }   // 2nd iteration $v is a reference to $a[1] ('b')
foreach ($a as &$v) { }   // 3rd iteration $v is a reference to $a[2] ('c')
foreach ($a as &$v) { }   // 4th iteration $v is a reference to $a[3] ('d')

                          // At the end of the foreach loop,
                          //    $v is still a reference to $a[3] ('d')

foreach ($a as $v) { }    // 1st iteration $v (still a reference to $a[3]) 
                          //    is set to a value of $a[0] ('a').
                          //    Because it is a reference to $a[3], 
                          //    it sets $a[3] to 'a'.
foreach ($a as $v) { }    // 2nd iteration $v (still a reference to $a[3]) 
                          //    is set to a value of $a[1] ('b').
                          //    Because it is a reference to $a[3], 
                          //    it sets $a[3] to 'b'.
foreach ($a as $v) { }    // 3rd iteration $v (still a reference to $a[3]) 
                          //    is set to a value of $a[2] ('c').
                          //    Because it is a reference to $a[3], 
                          //    it sets $a[3] to 'c'.
foreach ($a as $v) { }    // 4th iteration $v (still a reference to $a[3]) 
                          //    is set to a value of $a[3] ('c' since 
                          //       the last iteration).
                          //    Because it is a reference to $a[3], 
                          //    it sets $a[3] to 'c'.

  • @Manish Trivedi: Siehe die Warnung Teil dafür, warum dies geschieht. An deinem Programm ist nichts auszusetzen.

    – BoltClock

    11. Februar 2011 um 13:05 Uhr

  • Sehr gute Erklärung! Danke: Ich muss mich daran erinnern, dass man als Referenz / Dupe alle anderen Antworten auf Referenzen mit foreach nicht so gut erklärt wie Sie es hier getan haben!

    – Rizier123

    27. März 2015 um 15:45 Uhr

  • In deiner unset($v);warum ist $v außerhalb des Geltungsbereichs von foreachs zugänglich? :Ö

    – nawfal

    20. November 2015 um 13:15 Uhr

  • @nawfal – verstehe die Frage nicht … Der Gültigkeitsbereich lokaler PHP-Variablen befindet sich innerhalb einer Funktion, nicht einfach innerhalb einer Schleife

    – Markus Bäcker

    20. November 2015 um 13:17 Uhr

  • @MarkBaker danke. Du hast meine Frage beantwortet. Ich komme gerade mit PHP-Eigenheiten in den Griff 🙂

    – nawfal

    20. November 2015 um 13:40 Uhr

1646939049 897 Seltsames Verhalten von foreach
dimitis

Die erste foreach-Schleife nimmt, wie erwartet, keine Änderung am Array vor. Allerdings verursacht es $v jeweils eine Referenz zuzuweisen $a‘s Elemente, so dass, wenn die erste Schleife vorbei ist, $v ist in der Tat ein Hinweis auf $a[2].

Sobald die zweite Schleife beginnt, $v wird nun der Wert jedes Elements zugewiesen. Aber, $v ist bereits ein Hinweis auf $a[2]; daher wird jeder ihm zugewiesene Wert automatisch in das letzte Element des Arrays kopiert!

Also, während der ersten Iteration, $a[2] wird zu Null, dann zu Eins und dann wieder zu Eins und wird effektiv auf sich selbst kopiert. Um dieses Problem zu lösen, sollten Sie die Variablen, die Sie in Ihren foreach-Schleifen als Referenz verwenden, immer zurücksetzen – oder, noch besser, die ersteren ganz vermeiden.

988750cookie-checkSeltsames Verhalten von foreach

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy