Pourquoi PHP écrase-t-il les valeurs lorsque j'écrite deux fois dans ce tableau (par référence, par valeur)

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

  •  27-09-2019
  •  | 
  •  

Question

Si j'écrite deux fois par un tableau, une fois par référence, puis par valeur, PHP écrasera la dernière valeur du tableau si j'utilise le même nom de variable pour chaque boucle. Ceci est mieux illustré à travers un exemple:

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

Production:

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

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

Notez que je ne cherche pas de correctif, je cherche à comprendre pourquoi cela se produit. Notez également que cela ne se produit pas si les noms de variables de chaque boucle ne sont pas appelés chacun $element, donc je suppose que cela a à voir avec $element étant toujours dans la portée et une référence après la fin de la première boucle.

Était-ce utile?

La solution

Après la première boucle, $ l'élément est toujours une référence au dernier élément / valeur de $ array.
Vous pouvez le voir lorsque vous utilisez var_dump () au lieu de print_r ()

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

Notez que et dans &int(2).
Avec la deuxième boucle, vous attribuez des valeurs à $ élément. Et comme il s'agit toujours d'une référence, la valeur du tableau est également modifiée. Essayez-le avec

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

comme la deuxième boucle et vous verrez.
C'est donc plus ou moins la même chose que

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

(seulement avec des boucles et une multiplication ... Hé, j'ai dit "plus ou moins" ;-))

Autres conseils

Voici Une explication de l'homme lui-même:

$y = "some test";

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

Ici $y est une entrée de table de symbole faisant référence à une chaîne contenant "un test". Lors de la première itération, vous faites essentiellement:

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

Alors maintenant le stockage associé à $yest écrasé par la valeur de $myarray. Si $y est associé à un autre stockage via une référence, ce stockage sera modifié.

Disons maintenant que vous faites ceci:

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

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

Ici $y est associé au même stockage que $a par une référence ainsi lorsque la première itération:

$y = $myarray[0];

Le seul endroit où la chaîne "test" peut aller dans le stockage associé à $y.

C'est ainsi que vous résolvez ce problème:

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

foreach($array as $element) { }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top