Page 1 sur 1

bug foreach après modification du tableau par référence

Posté : 04 sept. 2017, 10:48
par carte-sd
Bonjour à tous,
Je ne sais pas si c'est une bizarrerie de PHP ou un bug (du coup je n'ose pas le rapporter), j'utilise PHP 7.1.9.
Un exemple vaut mieux que des mots :

Code : Tout sélectionner

<?php $messages = array( array( 'date' => mktime(11,11,11,9,23,2013), 'titre' => 'titre1', 'url' => 'url1.php' ), array( 'date' => time()-86400, 'titre' => 'titre2', 'url' => 'url2.php' ) ); foreach($messages as &$message){ $message['nouveau'] = (time() < $message['date']); // time() représente normalement un cookie qui stock une date j'ai retiré cette partie pour des raisons de clarté } $mLen = count($messages); for($i=0; $i<$mLen; $i++){ print $messages[$i]['titre'].'<br />'; } /* * titre1 * titre2 */ print '<hr />'; foreach($messages as $message){ print $message['titre'].'<br />'; } /* * titre1 * titre1 */ ?>
Est-ce un bug ?

Re: bug foreach après modification du tableau par référence

Posté : 04 sept. 2017, 15:56
par tesmet
Hello

Code : Tout sélectionner

foreach($messages as &$message){
Le & fait de $message un pointeur sur chacun des indexes de $messages et à la fin de la boucle foreach ce pointeur continuera d'exister sur le dernier index et toute affectation vers $message même via un second foreach affectera le dernier indexe de $messages. Ce n'est pas un bug mais le mode de fonctionnement qui ne peut pas être autre et si & est utilisé dans un foreach, alors il est recommander d'utiliser unset() après la boucle pour détruire la relation de pointeur.

Code : Tout sélectionner

foreach($messages as &$message){ $message['nouveau'] = (time() < $message['date']); // time() représente normalement un cookie qui stock une date j'ai retiré cette partie pour des raisons de clarté } unset($message);
Comme il semble y avoir eu de nombreux "bug report" tout à fait erronés sur le sujet, il est fortement conseillé de préférer un foreach de la forme:

Code : Tout sélectionner

foreach($messages as $index=>$message){ $messages[$index]['nouveau'] = (time() < $message['date']); // time() représente normalement un cookie qui stock une date j'ai retiré cette partie pour des raisons de clarté }

Re: bug foreach après modification du tableau par référence

Posté : 04 sept. 2017, 20:17
par carte-sd
Merci Lesmet pour ta réponse, c'est un comportement surprenant (pour moi en tout cas, dans le sens où je m'attendais à ce qu'il supprime tout seul la référence) mais j'ai bien compris le pourquoi du comment. J'ai bien fait de ne pas faire de rapport du coup :)