Perché PHP sovrascrive i valori quando iterazione attraverso questo array due volte (per riferimento, per valore)

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

  •  27-09-2019
  •  | 
  •  

Domanda

Se iterazione attraverso un array due volte, una volta per riferimento e poi per valore, PHP sovrascriverà l'ultimo valore nell'array se utilizzo lo stesso nome variabile per ogni ciclo. Questo è meglio illustrato attraverso un esempio:

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

Produzione:

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

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

Nota che non sto cercando una soluzione, sto cercando di capire perché sta accadendo. Si noti inoltre che non accade se i nomi delle variabili in ciascun ciclo non vengono chiamati ciascuno $element, quindi immagino che abbia a che fare con $element Ancora in portata e riferimento dopo la fine del primo ciclo.

È stato utile?

Soluzione

Dopo il primo elemento loop $ è ancora un riferimento all'ultimo elemento/valore di $ array.
Puoi vederlo quando usi var_dump () invece di print_r ()

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

Nota che e dentro &int(2).
Con il secondo ciclo assegni valori a $ elemento. E poiché è ancora un riferimento, anche il valore nell'array viene modificato. Provalo con

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

Come secondo ciclo e vedrai.
Quindi è più o meno uguale a

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

(Solo con loop e moltiplicazione ... Ehi, ho detto "più o meno" ;-))

Altri suggerimenti

Ecco una spiegazione dell'uomo stesso:

$y = "some test";

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

Qui $y è una voce della tabella dei simboli che fa riferimento a una stringa contenente "qualche test". Nella prima iterazione che fai essenzialmente:

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

Quindi ora l'archiviazione associata a $yè sovrascritto dal valore di $myarray. Se $y è associato ad qualche altro spazio di archiviazione attraverso un riferimento, che l'archiviazione verrà modificata.

Ora diciamo che lo fai:

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

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

Qui $y è associato allo stesso spazio di archiviazione $a attraverso un riferimento, quindi quando la prima iterazione fa:

$y = $myarray[0];

L'unico posto in cui può andare la stringa "test" è nell'archiviazione associata $y.

Ecco come risolveresti questo problema:

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

foreach($array as $element) { }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top