Přepisování persitentních proměnných – částí pole
- enlilcz
- Člen | 7
Mám v presenteru property:
<?php
/** @persistent array */
public $filters = array(
'gender' => NULL,
'age' => NULL,
);
?>
Pokud naplním jen klíč gender, Nette ignoruje původní obsah pole a natvrdo jej přepíše tím, co dostalo v requestu.
Zatím to řeším tíhle škaredým workaroundem:
<?php
public function startup()
{
$classVars = get_class_vars(get_class($this));
$this->filters = $this->filters + $classVars['filters'];
}
?>
- enlilcz
- Člen | 7
@jtousek: Mnohem lépe se mi s tím pracuje v poli v rámci aplikace. Když přidám vlastnost, stačí to upravit na jednom místě. Data pak v modelu sanitizuji, takže mi nikdo nemůže ani nic podstrčit.
@Jan Tvrdík: Feature? Pokud to pole je definované ve třídě, tak mi nikdo zvenku nemůže do defaultu nic podstrčit a očekávatelné chování je, že se přepíšou klíče pole, co přišly v requestu a zbytek se sloučí. Úplně stejně jako kdybych se třídou pracoval zevnitř.
- Filip Procházka
- Moderator | 4668
@**enlilcz**: to je ale tvoje chyba, že to očekáváš ;) Nikdy nevěř vstupu od uživatele. Tohle je jeden parametr, tedy jeho hodnotu může ovlivnit uživatel a může i smazat co v něm je. Pokud ti to vadí, udělej dva parametry.
Naopak tvůj požadavek je hloupost, protože se to příčí chování jazyka. Nekonzistence je špatná. Nikdo ti samozřejmě nebrání si to hacknout, ale to už jde na tvé triko ;)
Správně bys to měl dělat takto, pokud tam chceš vždy všechny klíče.
/** @persistent array */
public $filters = array();
/** @var array */
static $filterDefaults = array(
'gender' => NULL,
'age' => NULL,
);
public function startup()
{
$this->filters = $this->filters + static::$filterDefaults;
}
- jtousek
- Člen | 951
@HosipLan: Jestli jsem to dobře pochopil tak mu jde o změnu pouze jednoho parametru, např. odkazem. Správné řešení je tedy v šabloně předávat ne jen ten upravený filtr ale původní parametr $filters + pole s upraveným filtrem.
@enlilcz: A to je tak těžké si z těch několika perzistentních parametrů v metodě startup poskládat pole a dále pracovat s nim?
Editoval jtousek (24. 5. 2012 13:43)
- Ascaria
- Člen | 187
Mít persistentní jen jeden parametr považuju za velké plus (pracuji na svém datagridu, který na všechno potřebuje jen jeden argument), lehko se přenáší a nemusí se kontrolovat přítomnost nepovinných parametrů. Takže HosipLan ti to shrnul přesně, jen namísto něj bych ale udělal:
/** @persistent */
public $filters;
// a nebo
public $filters = null;
Protože se pak líp ta hodnota vyruší, nemusíš tápat v kódu jakou to má výchozí hodnotu, jen napíšeš = null a máš jistotu že ti to z adresy zmizí.
Editoval Ascaria (24. 5. 2012 14:48)
- Filip Procházka
- Moderator | 4668
@**Ascaria**: což je hloupost, protože Nette ti automaticky vynucuje
datový typ. Tedy array()
tam není jen tak, aby to vypadalo
pěkně ;)
- Ascaria
- Člen | 187
HosipLan napsal(a):
@**Ascaria**: což je hloupost, protože Nette ti automaticky vynucuje datový typ. Tedy
array()
tam není jen tak, aby to vypadalo pěkně ;)
V tom případě pak něco jako:
/** @persistent Array */
public $filters = null;
Podle pravidel PHP se pak hodnota null přidá do výčtu akceptovaných hodnot. Ověřit si to lze třeba na metodě function(Array $a) versus function(Array $a = null).
- Filip Procházka
- Moderator | 4668
@**Ascaria**: opět hloupost. PHP nativně neumí annotace, umí
ovšem nativně říct, jaký je výchozí
datový typ. A NULL
je vždycky výchozí hodnota, pokud
žádnou neuvedeš ⇒ zbytečnost.
Editoval HosipLan (24. 5. 2012 16:05)