par , 15/12/2015 à 17h39 (774 Affichages)
Comme cet article le décrit très bien, les références en PHP peuvent donner lieu à des résultats inattendus lorsqu'elles sont utilisées dans une boucle foreach.
J'aimerais cependant y apporter le complément que ce résultat est dû au nommage des containers. Si le nom de la variable utilisée dans la deuxième itération est différent ou si la variable de la première itération est supprimée, le résultat sera celui attendu.
1 2 3 4 5 6
| <?php
$a = array('a', 'b', 'c', 'd');
foreach($a as &$v) {}
unset($v); // suppression de la variable (du container)
foreach($a as &$v) {}
print_r($a); // ['a','b','c','d'] |
Certaines fonctions PHP de traitement de tableaux (préfixe array_) ne copient pas les variables et travaillent directement avec le pointeur interne du tableau. D'un point de vue mémoire, c'est plus optimale mais d'un point de vue pratique, ça cause un problème dans le cas suivant:
1 2 3 4 5 6 7 8
| <?php
$a = array('a', 'b', 'c', 'd');
$b = array('e','f','g','h');
foreach($a as $i => &$v) {
echo $i; // $i vaut toujours 0
$a = array_merge($a, $b); // array_merge réinitialise le pointeur interne du tableau à 0 et cause une boucle infinie.
} |
La fonction array_merge ne restaure pas le pointeur du tableau, au contraire il la réinitialise à 0 et foreach, itérant sur le pointeur interne du même tableau, se retrouve à nouveau au début du tableau.
Détail complet du comportement foreach. http://stackoverflow.com/questions/1...-actually-work