webdesign / development + awesome
archivovaný archívny archív
...alebo skôr feature? Keď v PHP používate foreach s referenciou (&), treba si dávať veľký pozor. Môžu sa diať vcelku záhadné veci. Zoberme si takýto príklad:
$ciselka = array(1,2,3,4,5,6); foreach ($ciselka as &$cislo) $cislo *= 10; foreach ($ciselka as $cislo) echo "$cislo ";
V prvom foreach cykle všetky čísla v poli vynásobíme desiatimi a v druhom ich vypíšeme - triviálna vec, takže výsledok je úplne jasný:
10 20 30 40 50 60
Alebo aj nie? Ak to skúsite naozaj spustiť v PHP, uvidíte niečo trocha iné:
10 20 30 40 50 50
- WTF is goin' on?
Prečo sú posledné 2 prvky rovnaké? Cyklus foreach funguje tak, že do pomocnej premennej ($cislo
) vždy kopíruje aktuálny prvok poľa a podľa toho, či pred ňu nedáme alebo dáme "&" sa buď do nej skopíruje hodnota aktuálneho prvku alebo odkaz/pointer na aktuálny prvok. V prvom cykle úkladáme do pomocnej premennej odkazy na prvky poľa, takže po skončení je v premennej $cislo
odkaz na posledný prvok.
Ak by sme teraz premennej $cislo
priradili hocijakú hodnotu, zmenila by sa aj hodnota posledného prvku poľa. A presne toto sa deje pri druhom cykle foreach - postupne, ako prechádzame poľom, sa priraďujú premennej $cislo
hodnoty 10, 20, 30, 40, 50. Takže je logické, že keď prijdeme na posledný prvok, je v ňom hodnota predposledného prvku.
Ako tomu zabrániť? Nuž velice jednoducho. :p
Za prvý foreach stačí napísať unset($cislo)
. Premenná prestane existovať, odkaz sa zruší a v druhom cykle sa úplne nanovo vytvorí premenná $cislo
, takže sa nič nebude prepisovať.
Je diskutabilné, či sa toto vôbec dá označiť ako bug... Na jednej strane prakticky nepredvídateľné, ale na druhej aj celkom logické. Asi preto je to v PHP nezmenené odvtedy ako existuje foreach s referenciou.
Archivovaný archív je bez komentárov. Radšej.
čo ty na to?
komentuj ku každému komentáru sa v databáze ukladá iba meno, text a dátum, iba za účelom zobrazenia pod článkomneukladá sa email, IP adresa ani informácie o prehliadači a údaje sa nepoužívajú na reklamu, newsletter, na žiadnu ekonomickú aktivitu, nikam sa neposielajú, sú v databáze len aby sa mohli zobraziť pod článkom