Automatická validace parametrů v presenteru pomocí anotací
- Jan Tvrdík
- Nette guru | 2595
Implementoval jsem automatickou validaci parametrů
v presenteru pomocí @param
anotací.
/**
* @param bool
* @param int|array
* @param string
*/
public function renderFoo($a, $b = FALSE, $c = NULL) {...}
Stručná pravidla chování v tomto případě:
- Pokud
$a
bude'1'
nebo'0'
, bude automaticky přetypován naboolean
. - Pokud
$a
není ani boolean ani'1'
nebo'0'
, skončí skript sBadRequestException
. - Pokud
$a
nebude existovat nebo budeNULL
, skončí skript sBadRequestException
. - Pokud
$b
bude např.'123'
, bude automaticky přetypován naint
. - Pokud
$b
nebude existovat nebo budeNULL
, bude dosazena výchozí hodnota, tj.FALSE
. - Pokud
$b
nebude ani celé číslo ani celočíselný řetězec ani pole, skončí skript sBadRequestException
. - Pokud
$c
nebude řetězec, skončí skript sBadRequestException
. - Pokud
$c
nebude existovat nebo budeNULL
, bude dosazena výchozí hodnota, tj.NULL
.
Zdrojový kód je k dispozici ve dvou variantách na GitHubu (varianty se liší tím, co ještě dovolí automaticky konvertovat).
Protože to může potenciálně způsobovat BC break*, tak je potřeba do
BasePresenteru
umístit public $validateParams = TRUE;
pro explicitní zapnutí validace. Časem možná sepíši
RFC (důvody a problémy).
Chtěly byste něco takového v Nette? Sepsal jsem RFC.
*V případě, že používáte anotaci @param
a její hodnota
je chybná, nebo nepočítáte s automatickým přetypováním, nebo
spoléháte na dříve fungující přetypování hodnoty na typ výchozí
hodnoty, pokud existuje.
Editoval Jan Tvrdík (28. 2. 2011 23:52)
- Filip Procházka
- Moderator | 4668
Líbilo by se mi automatické přetypování, ale validace si rád dělám přímo v metodě.
- Jan Tvrdík
- Nette guru | 2595
Pokud anotace nebude uvedena, bude se to chovat normálně s tím rozdílem, že nebude fungovat automatické přetypování na typ výchozí hodnoty (to je v Nette teď).
- Honza Marek
- Člen | 1664
Je to takové magické, ale to je ostatně ten trik s přetypováním podle výchozí hodnoty taky.
- Inza
- Člen | 330
Jsem jednoznačně PRO zaintegrování do Nette! A pokud je implementačně reálné to udělat tak, že pokud by se @param anotace neuvedly, tak by se to chovalo jako se to chová nyní, bylo by to řešení, které IMHO řeší vše.
A pro hnidopichy, kteří neradi „magické“ věci, tam klidně můžeme ponechat tu nutnost tuto featuru zapnout v BasePresenteru…
- jtousek
- Člen | 951
Jsem rozhodně PRO. Jen bych měl drobný dotaz, když u některého
parametru chci umožnit hodnotu NULL, musím přímo uvést např.
@param int|NULL
?
Bylo by hezké, kdyby se stejně chovaly i perzistentní
parametry komponent (tedy i presenterů). Tam by to samozřejmě
nebylo podle anotace @param
, ale podle @var
.
- Jan Tvrdík
- Nette guru | 2595
mkoubik napsal(a):
Myslím, že by byl lepší jiný název anotace, aby to nekolidovalo s phpdocem.
Jaký smysl by mělo deklarovat něco jiného v @param
, než
chci skutečně validovat? Zvolená anotace zcela úmyslně odpovídá
phpDoc.
jtousek napsal(a):
Jsem rozhodně PRO. Jen bych měl drobný dotaz, když u některého parametru chci umožnit hodnotu NULL, musím přímo uvést např.
@param int|NULL
?
Pokud chceš umožnit hodnotu NULL
, použij např.
@param int|NULL
. Pokud chceš, aby byl daný parametr nepovinný
(což bude výrazně častější případ), deklaruj mu jako výchozí hodnotu
NULL
.
Samu skutečnost, kdy Nette umožňuje poslat NULL
do povinného
parametru, považuji za velmi podivnou.
- Jan Tvrdík
- Nette guru | 2595
Hodnoty výchozích parametrů se nevalidují, takže tam lze uvést i něco, co neodpovídá anotaci.
- Jan Tvrdík
- Nette guru | 2595
mkoubik napsal(a):
Jaký smysl by mělo deklarovat něco jiného v
@param
, než chci skutečně validovat? Zvolená anotace zcela úmyslně odpovídá phpDoc.Například chci v dokumentaci uvést typ, ale validovat chci ručně.
V tom případě si tu validaci nezapínej vůbec nebo uveď nakonec
|mixed
, čímž validaci daného parametru zrušíš.
- Honza Marek
- Člen | 1664
Co si myslíte o tom, že by se validace zapínala další anotací? Potom odpadne riziko, že to někomu bude dělat něco co nechce. Na druhou stranu je to více psaní a na tu anotaci lze zapomenout a přesto na ni spoléhat.
/**
* @ValidateParams
* @param bool
* @param int|array
* @param string
*/
public function renderFoo($a, $b = FALSE, $c = NULL) {...}
- Jan Tvrdík
- Nette guru | 2595
Co takhle kompromis? – V BasePresenteru
se nastaví výchozí
chování a zvláštní anotací u dané metody lze toto výchozí chování
přepsat.
- Jan Tvrdík
- Nette guru | 2595
Nebude lepší přejmenovat tu proměnnou v Presenteru
z
$validateParams
na $autoValidateParams
(analogie k
$autoCanonicalize
)?
Ohledně těch anotací mě napadá @enableParamsValidation
a
@disableParamsValidation
, ale je to dost dlouhé. Co třeba
@paramsValidation on
a @paramsValidation off
? (Velké
písmeno na začátku anotace se mi nelíbí.)
- Patrik Votoček
- Člen | 2221
Hezké zapínání anotací na první pohled cool na druhý vůbec (sem strašně línej proto volím cestu nastavením v base presenteru). Jinak taky bych raději true/false nez on/off (jsem programátor stejně jako počítám od nuly tak nepoužívám ano/ne yes/no nebo on/off na to mám prostě true/false – ostatní připadá v úvahu pouze u více jak 2 možností a to ještě za předpokladu že tou možností není autodetect kterej se dá řešit pomocí null)
- jtousek
- Člen | 951
@westrem: Zajímavé, ale většinou nepotřebuješ omezovat id na 30 apod. Výjimka by mohla být třeba že měsíc je 1–12, ale těch případů není tolik aby to bylo potřeba. Automatické přetipování je zde na místě, tvé řešení mi připadá zbytečně komplexní. ;)
K diskusi @ValidateParams / @ParamsValidation / whatever.
Anotace by rozhodně měla být boolean true/false. A myslím, že by se měla
jmenovat stejně nebo podobně jako samotná proměnná. Např. tedy
public $autoValidateParams = TRUE
a
@ValidateParams false
.
Co ty perzistentní parametry? Divím se, že se k tomu nikdo nevyjádřil.
- Jan Tvrdík
- Nette guru | 2595
jtousek napsal(a):
Co ty perzistentní parametry?
Kouknu, jak složité by to bylo a podle toho se rozhodnu, zda podporu pro jejich validaci dopíšu.