PHP - bug při iteraci pomocí foreach

Narazil jsem dnes na velmi povedený bug v PHP. Ukažme si ho na příkladu:

$arr = array(1, 2, 3, 4, 5);

foreach ($arr as &$x) {}

foreach ($arr as $x) {
	echo $x;
}

Očekávaným výsledkem je "12345". Místo toho se ale vypíše "12344" :)

Chyba nastane v případě, že iterujeme pole nejprve přes &$proměnná, a pak znovu přes stejnou proměnnou ale bez operátoru reference. Pokud operátor reference uvedeme i v druhé iteraci, chyba se neobjeví.

Bug byl nahlášen už v roce 2004, ale stále ještě není opraven.

Hodnocení

Komentáře

[1] paranoiq
2011-07-01 12:31:17

souhlasím s autory v tom, že tohle není bug, ale špatné užití reference. viz http://schlueters.de/blog/archives/141-References-and-foreach.html

2011-07-01 13:38:11

Viz také můj článek http://php.vrana.cz/paralelni-zpracovani.php#curl z roku 2005 (stejné riziko tam zmiňuji mimochodem).

[3] Ondra
2011-07-01 14:06:53

Z tohoto důvodu po foreach využívajícím reference vždy pro jistotu volám unset.

foreach ($arr as &$x) {}
unset($x);

[4] Dundee
2011-07-06 20:34:48

Jak už jsem psal jinde: Ten článek neříká, proč je tohle chování správné, pouze ukazuje, proč se to tak děje. A je to rozhodné chování. Správně by se proměnná, přes kterou chci iterovat měla nejprve "resetovat".

Komentáře již nelze přidávat