213 votes

PHP Pass par référence dans foreach

J'ai ce code:

 $a = array ('zero','one','two', 'three');

foreach ($a as &$v) {

}

foreach ($a as $v) {
  echo $v.PHP_EOL;
}
 

Quelqu'un peut-il expliquer pourquoi le résultat est: zéro un deux deux.

De zend guide d'étude de certification.

188voto

M S Points 1150

J'ai passer quelques heures à comprendre pourquoi un[3] est en train de changer à chaque itération.C'est ce que l'explication que j'ai eu.

Il existe deux types de variable en PHP. Normale de la variable et la variable de référence. Si nous attribuer une référence d'une variable à une autre variable, la variable devient variable de référence.

par exemple, dans

$a = array('zero', 'one', 'two', 'three');

si nous ne

$v = &$a[0]

le 0e élément ($a[0]) devient une variable de référence. $v est orienté vers cette variable. Il y a de si nous faisons tout changement en $v il sera reflété dans $a[0] , et vice-versa.

maintenant, si nous ne

$v = &$a[1]

$a[1] deviendra une variable de référence et d' $a[0] deviendra une variable normale (Car personne d'autre ne se pointant $a[0] il est converti à la normale de la variable. PHP est assez intelligent pour en faire une variable normale quand personne n'est pointant vers)

C'est ce qui se passe dans la première boucle

foreach ($a as &$v) {

}

Après la dernière itération $a[3] est une variable de référence.

Depuis $v vers $a[3] tout changement en $v se traduit par une variation $a[3]

dans la seconde boucle,

foreach ($a as $v) {
  echo $v.'-'.$a[3].PHP_EOL;
}

dans chaque itération, comme $v changements, $a[3] changements. (coz $v encore des points de $a[3]). C'est la raison pour laquelle $a[3] change à chaque itération.

Dans la dernière itération, $v est affectée de la valeur "deux". Depuis $v points de $a[3], $a[3] maintenant avoir la valeur "deux". C'est ce qui est imprimé dans la dernière itération. Et donc le "deux" est répété à nouveau.

157voto

Macmade Points 27414

Parce que sur la seconde boucle, $v est toujours une référence au dernier élément du tableau, il est donc écrasé à chaque fois.

Vous pouvez le voir comme ça:

 $a = array ('zero','one','two', 'three');

foreach ($a as &$v) {

}

foreach ($a as $v) {
  echo $v.'-'.$a[3].PHP_EOL;
}
 

Comme vous pouvez le constater, le dernier élément du tableau prend la valeur de la boucle en cours: "zéro", "un", "deux", puis "deux" ...

54voto

TaeL Points 312

première boucle

 $v = $a[0];
$v = $a[1];
$v = $a[2];
$v = $a[3];
 

Oui! $ v = $ a [3] position actuelle

deuxième boucle

 $a[3] = $v = $a[0], echo $v; // same as $a[3] and $a[0] == 'zero'
$a[3] = $v = $a[1], echo $v; // same as $a[3] and $a[1] == 'one'
$a[3] = $v = $a[2], echo $v; // same as $a[3] and $a[2] == 'two'
$a[3] = $v = $a[3], echo $v; // same as $a[3] and $a[3] == 'two'
 

car $ a [3] attribué par avant le traitement

5voto

TTT Points 11

Ce :

 $a = array ('zero','one','two', 'three');

foreach ($a as &$v) {

}

foreach ($a as $v) {
    echo $v.PHP_EOL;
}
 

est le même que

 $a = array ('zero','one','two', 'three');

$v = &$a[3];

for ($i = 0; $i < 4; $i++) {
    $v = $a[$i];
    echo $v.PHP_EOL; 
}
 

OU

 $a = array ('zero','one','two', 'three');

for ($i = 0; $i < 4; $i++) {
    $a[3] = $a[$i];
    echo $a[3].PHP_EOL; 
}
 

OU

 $a = array ('zero','one','two', 'three');

$a[3] = $a[0];
echo $a[3].PHP_EOL;

$a[3] = $a[1]; 
echo $a[3].PHP_EOL;

$a[3] = $a[2];
echo $a[3].PHP_EOL;

$a[3] = $a[3]; 
echo $a[3].PHP_EOL;
 

4voto

Je ne suis pas sûr de pouvoir expliquer pourquoi, mais cela est documenté dans le manuel .

Le commentaire fournit également des solutions si c'est ce que vous recherchez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X