Explication d'un code php

manio11 Messages postés 49 Statut Membre -  
manio11 Messages postés 49 Statut Membre -
Bonjour,

En faisant des recherches en php, je suis tombé sur le code suivant :

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

foreach($a as &$v){
}

foreach($a as $v){
}

print_r($a);

/************ ce qui affiche ******************/
Array
(
[0] => zero
[1] => one
[2] => one
)

je voudrai que quelqu'un m'explique clairement pourquoi les 2 derniers éléments du tableau sont identiques.je comprends qu'à la fin de la premiere boucle, &$v fait refence à $a[2], et ensuite ??
A voir également:

10 réponses

Alain_42 Messages postés 5413 Statut Membre 894
 
bonsoir,



foreach($a as &$v){
}

foreach($a as $v){
}

il n'y a aucune instruction dans tes deux boucles foreach donc ça fait rien
print_r($a);

ce qui t'es affiché l'est par print_r

de plus foreach($a as &$v) me parait bizarre je n'ai jamais vu une variable commençant par &

en php elle commencent toujours par $

es ce une erreur de frappe ?
0
niahoo Messages postés 262 Statut Membre 19
 
hum.. même en supprimant les foreach, le print_r devrait afficher


Array 
( 
[0] => zero 
[1] => one 
[2] => two
)



or il affiche

Array 
( 
[0] => zero 
[1] => one 
[2] => one 
)
0
Alain_42 Messages postés 5413 Statut Membre 894
 
tu mets quoi comme tags pour php

<?

?>

ou
<?php

?>
0
niahoo Messages postés 262 Statut Membre 19
 
j'ai testé chez moi, si j'enleve une des boucles foreach ou les deux ça affiche bien le tableau comme il devrait être, avec 'two' à la fin.

aurais-tu découvert un bug ? car apparement mettre deux foreach détruit la deuxieme variable.

la variable qui commence par & ne génère pas d'erreur
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
niahoo Messages postés 262 Statut Membre 19
 
houla c'est même bizzare:

<?php
$a = array('zero', 'one' , 'two'); 

foreach($a as &$v){ 
} 

foreach($a as $v){ 
} 


print_r($a); 
?>


affiche un tableau erroné

<?php
$a = array('zero', 'one' , 'two'); 

foreach($a as &$v){ 
} 

foreach($a as &$v){ 
} 


print_r($a); 
?>


avec deux fois la variable avec & affiche le bon tableau. je peux mettre 20 fois le foreach avec toutes les varibles qui commencent par & le tableau est correct




j'ai essayé à peu près tout, on peut mettre autant de foreach qu'on veut, mais du moment qu'on en a au moins un avec le & et au moins un sans, ça affiche un mauvais tableau


et enfin


<?php
$a = array('zero', 'one' , 'two'); 



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




print_r($a); 
?>


(variables de nom différent) affiche le bon tableau
0
niahoo Messages postés 262 Statut Membre 19
 
allez je continue les tests:

<?php
$a = array('zero', 'one' , 'two'); 

foreach($a as $v){ 
echo $v;
echo "<br />";
}

print_r($a);
echo "<br />";

foreach($a as &$v){ 
echo $v;
echo "<br />";
} 

print_r($a);
echo "<br />";

?>

donne :
zero
one
two
Array ( [0] => zero [1] => one [2] => two )
zero
one
two
Array ( [0] => zero [1] => one [2] => two )

et

<?php
$a = array('zero', 'one' , 'two'); 

foreach($a as &$v){ 
echo $v;
echo "<br />";
}

print_r($a);
echo "<br />";

foreach($a as $v){ 
echo $v;
echo "<br />";
} 

print_r($a);
echo "<br />";

?>

donne :
zero
one
two
Array ( [0] => zero [1] => one [2] => two )
zero
one
one
Array ( [0] => zero [1] => one [2] => one )



donc la troisieme variable n'est détruite que quand je place la varaible avec le & en premier, mai selle n'est détruite que quand on l'utilise sans le '&'
0
Alain_42 Messages postés 5413 Statut Membre 894
 
Bon j'ai fait des essai aussi, si on laisse une seulle des deux foraech pas de pb, par contre si on laisse les deux mais sans le & denat le$v pas de pb non plus

par contre si on laisse les deux foreach avec le & devant $v dans la première on a le pb

j'ai donc creusé la question

le & devant une varaible permet de passer un variable à une fonction par sa référence (adresse) au lieu de la passer par a valeur

dans notre cas ça doit faire quelques chose de bizarre.

j'ai même essayé en mettant plus de nombres c'est toujours les deux derniers qui sont répétés.

et le pb est aussi du au fait que $v est identique dans les deux boucles

si on met &$v1 dans la 1 et $v dans la 2 on a plus le pb

Une question à quoi il te sert ce code ??
0
niahoo Messages postés 262 Statut Membre 19
 
hmm merci pour ce début d'explication, c'est génial, je viens de découvrir qu'on peut utiliser des pointeurs, comme en C (enfin je pense j'avasi lu un truc la dessus dans un tuto sur le C du site du zero mais j'ai jamasi fait de C)


le truc c'est que ok, on passe l'adresse et non la valeur, donc ok pour le bug dans mes echo,

mais on devrait trouver la bonne valeur dans le print_r quand même. donc ça modifie la variable à son adresse...
0
niahoo Messages postés 262 Statut Membre 19
 
et je serais curieux de savoir comment t'as trouvé l'info, car dans google j'ai cherché "php & variables" ou " "&$" " etc.. mais tu te doutes que taper '&' dans google sert à rien ^^


sinon son code il sert à rient tel quel.. ou plutôt justement à montrer une astuce / faille à exploiter pour coder malin
0
Alain_42 Messages postés 5413 Statut Membre 894
 
ça modifie le pointeur si on utilises la même variable $v dans les deux foreach

si dans la première on met $v1 par ex il n'y a plus de pb

pour trouver j'ai mis dans G.. "php & devant la variable"
0
manio11 Messages postés 49 Statut Membre 2
 
salut à vous, et desolé pour le retard.

merci d'avoir essayé de comprendre le code.Je rappelle qu'il nya pas d'erreur dans ce code.Je l'ai lu dans un livre en anglais, je l'ai traduit et c'est expliqué comme suit :
- le premier foreach ne fait aucune modification du tableau, cependant $v fait référence à chaque élément du tableau de $a tel qu'au moment de la fin de la boucle, $v fait reference à $a[2]
- quand la deuxieme boucle commence, $v est maintenant affecté à la valeur de chaque élément. cependant $v est déjà une référence à $a[2]; par conséquent, toute valeur attribuée à celui-ci sera copiée automatiquement dans le dernier élément du tableau! Ainsi, au cours de la première itération, $a[2] sera égale à "zero", puis à "one", et puis à "one" encore, effectivement copié sur lui-même.

Pour résoudre ce problème, vous devez toujours désactiver (unset) les variables que vous utilisez dans
votre des boucles foreach, ou mieux encore, éviter d'utiliser tout l'ancien.


je vous avoue que je ne comprends pas toujours pourquoi à la 3eme itération, $a[2] est egale à "one"
0