Warum überschreibt PHP Werte, wenn ich dieses Array zweimal durch dieses Array iteriere (durch Bezugnahme, nach Wert)

StackOverflow https://stackoverflow.com/questions/2645499

  •  27-09-2019
  •  | 
  •  

Frage

Wenn ich zweimal ein Array durch die Referenz und dann nach Wert durch ein Array iteriere, überschreibt PHP den letzten Wert im Array, wenn ich für jede Schleife denselben Variablennamen verwende. Dies wird am besten durch ein Beispiel dargestellt:

$array = range(1,5);
foreach($array as &$element)
{
  $element *= 2;
}
print_r($array);
foreach($array as $element) { }
print_r($array);

Ausgabe:

Array ([0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 )

Array ([0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 8 )

Beachten Sie, dass ich nicht nach einer Lösung suche, ich suche zu verstehen, warum dies geschieht. Beachten Sie auch, dass es nicht geschieht, wenn die Variablennamen in jeder Schleife nicht jeweils aufgerufen werden $element, Ich vermute also, es hat damit zu tun $element Immer noch im Bereich und eine Referenz nach dem Ende der ersten Schleife.

War es hilfreich?

Lösung

Nach dem ersten Loop $ Element ist immer noch ein Hinweis auf das letzte Element/den letzten Wert von $ array.
Sie können das sehen, wenn Sie var_dump () anstelle von print_r () verwenden

array(5) {
  [0]=>
  int(2)
...
  [4]=>
  &int(2)
}

Beachten Sie, dass & in &int(2).
Mit der zweiten Schleife weisen Sie $ Element Werte zu. Und da es sich immer noch um eine Referenz handelt, wird auch der Wert im Array geändert. Versuchen Sie es mit

foreach($array as $element)
{
  var_dump($array);
}

Als zweite Schleife und Sie werden sehen.
Es ist also mehr oder weniger gleich wie

$array = range(1,5);
$element = &$array[4];
$element = $array[3];
// and $element = $array[4];
echo $array[4];

(Nur mit Schleifen und Multiplikation ... hey, ich sagte "mehr oder weniger" ;-))

Andere Tipps

Hier ist eine Erklärung vom Mann selbst:

$y = "some test";

foreach ($myarray as $y) {
    print "$y\n";
}

Hier $y ist ein Symbol -Tabelleneintrag, der auf eine Zeichenfolge verweist, die "einen Test" enthält. Bei der ersten Iteration tun Sie im Wesentlichen:

$y = $myarray[0];  // Not necessarily 0, just the 1st element

Also jetzt der Speicher, der damit verbunden ist $ywird durch den Wert von überschrieben $myarray. Wenn $y ist mit einem anderen Speicher durch eine Referenz verbunden, dass der Speicher geändert wird.

Nehmen wir jetzt an, Sie tun dies:

$myarray = array("Test");
$a = "A string";
$y = &$a;

foreach ($myarray as $y) {
    print "$y\n";
}

Hier $y ist mit der gleichen Speicherung verbunden wie $a Durch eine Referenz, wenn die erste Iteration der Fall ist:

$y = $myarray[0];

Der einzige Ort, an dem "Test" String gehen kann $y.

So würden Sie dieses Problem beheben:

foreach($array as &$element)
{
    $element *= 2;
}
unset($element); #gets rid of the reference and cleans the var for re-use.

foreach($array as $element) { }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top