Bezpečnější foreach v latte
- Honza Marek
- Člen | 1664
V PHP mě irituje ta vlastnost foreache, že dokáže přepsat dříve definovanou proměnnou, která se nešťastnou shodou okolností jmenuje stejně jako proměnná, do které foreach ukládá procházené prvky.
$name = 'name';
foreach (array('a', 'b', 'c') as $name) {
}
echo $name; // vypíše c místo name
To vede k občasným záhadným chybám v šablonách. Nemohlo by tedy latte předchozí proměnnou (pokud existuje) před foreachem zazálohovat a pak jí navrátit původní obsah?
- David Grudl
- Nette Core | 8227
Taky jsem na to párkrát narazil, ale nejsem si vědom žádného non-WTF způsobu, jak to řešit.
- Honza Marek
- Člen | 1664
DG: vyparsovat z „expression as $a ⇒ $b“ názvy proměnných za as, kouknout na ně v get_defined_vars. Pak by možná stačilo vyhodit laděnku s varováním a nemuselo by se nijak čarovat se zálohováním původních hodnot.
Foowie: To je k ničemu. Pokud mi foreach něco omylem přepíše nebo omylem smaže, to vyjde na stejno.
- Tomáš Kolinger
- Člen | 136
V případě přepsání vyhodit laděnku…
To zálohování je víc WTF, než samotná vlastnost PHP. Hlavně když si na to člověk zvykl.
- David Grudl
- Nette Core | 8227
Honza Marek napsal(a):
DG: vyparsovat z „expression as $a ⇒ $b“ názvy proměnných za as, kouknout na ně v get_defined_vars. Pak by možná stačilo vyhodit laděnku s varováním a nemuselo by se nijak čarovat se zálohováním původních hodnot.
Jako že by
{foreach $cokoliv as $item}...{/foreach}
{foreach $cokoliv as $item}...{/foreach}
Vyhodilo varování, že si mám v každém cyklu vymyslet jinou proměnou? Olalá!
- juzna.cz
- Člen | 248
Fixing magic with more magic :)
Taky se mi parkrat stalo, ze jsem kvuli tomuto zuril a chtel to zmenit. Ale jak
se clovek uklidni, dojde mu, ze by vznikly daleko vetsi WTF a ze by v budoucnu
asi zuril jeste vic.
(toto aspon kazdemu dojde, pze je to tak v PHP; ale kdo by pak mohl tusit, jak se chova latte, ktere do detailu nezna)
Spise bych to resil nejakou statickou analyzou na urovni IDE
- paranoiq
- Člen | 392
pořád nerozumím na co vlastně reaguješ :]
- k čemu unsetování před cyklem, když se stejně v cyklu přepíše?
- jak „pojmenovat aby nekolidovala“? tahle debata je právě o tom jak onu kolizi rozumě detekovat (a asi to nejde)
@jtousek: to ale odporuje konvenci vykřičníku ve zbytku Latte
- mkoubik
- Člen | 728
Reagoval jsem na:
někdy je ale účelem, aby poslední hodnota zůstala v proměnné
Navrhovaná úprava (vyhazovaní notice) by tohle nerozbila (pokud jsi tu proměnnou nepoužil už předtím).
// tady $item neexistuje
foreach ($items as $item) { ... }
// tady $item obsahuje poslední položku, no problem
- Honza Marek
- Člen | 1664
David Grudl napsal(a):
Jako že by
{foreach $cokoliv as $item}...{/foreach} {foreach $cokoliv as $item}...{/foreach}
Vyhodilo varování, že si mám v každém cyklu vymyslet jinou proměnou? Olalá!
No tak pak se to bude muset kontrolovat jen proti $template->getParameters()… #tonoucisesteblachyta
- uestla
- Backer | 799
Nedá mi to nereagovat:
Myslím, že tohle už by bylo až moc, mohlo by to dokonce býti i na škodu.
PHP holt takové je, a faktu, že iterační proměnné jsou po doběhnutí skriptu „obsazené“ hodnotami z poslední iterace, může někdo využívat.
Pak je jakákoli machinace (jako udělat iterační proměnné lokální jen pro vnitřek cyklu, kontrola předchozí obsazenosti proměnné se stejným jménem, atd.) vyloženě nežádoucí.
Editoval uestla (12. 6. 2012 0:02)