Autor wpisu: singles, dodany: 11.10.2011 22:15, tagi: php, zend_framework
Jednym z najbardziej znanych komponentów ZendFramework’a jest Zend_Form
. Na temat tego komponentu powiedziano wiele dobrego i złego, a opanowanie go nie należy do rzeczy stosunkowo łatwych. Dekoratory, filtry, validatory – sporo rzeczy do nauki. Dzisiaj chciałbym jednak skupić się na problemie dość często spotykanym i jego rozwiązaniu. Mianowicie chodzi o sprawdzenie, czy dana wartość jest większa od zadanej, ale w momencie, kiedy nie jest ona liczbą całkowitą.
Przykład
Przypuścmy, ze mamy formularz, w którym musimy zdefiniować cenę przedmiotu, ale nie może ona być niższa niż 0,90zł.
Kod realizujący to zadanie z wykorzystaniem Zend_Form
mógłby wyglądać następująco:
$form = new Zend_Form(); $element = new Zend_Form_Element_Text('val'); $element->addValidator(new Zend_Validate_GreaterThan(array('min' => 0.90))); $form->addElement($element); //input values $data = array('val' => "0,93"); var_dump($form->isValid($data)); // false
Dlaczego dane nie zostały uznane za prawidłowe? Z prostego powodu – w Polsce cześć ułamkową zapisujemy po przecinku, a nie po kropce. Podczas porównania PHP zamienia ciąg tekstowy na liczbę, co w wyniku prowadzi do porównania 0 z 0,90.
echo (float)'0,'93'; //gives 0
Rozwiązanie
Rozwiązaniem tego problemu, jest zmiana wartości zlokalizowanej na znormalizowaną. Dokonać tego możemy automatycznie za pomocą mechanizmu filtrów, gdyż są one stosowane przed walidacją. Musimy dopilnować, żeby przed walidacją wartość 0,90 wyglądała tak: 0.90.
Rozwiązaniem będzie zastosowanie filtra przeznaczonego specjalnie dla tego celu, mianowicie: Zend_Filter_LocalizedToNormalized
(patrz dokumentacja). Automatycznie rozpoznaje on używane locale i zwraca znormalizowaną wartość. Poprzedni przykład, tym razem działający:
$form = new Zend_Form(); $element = new Zend_Form_Element_Text('val'); $element->addValidator(new Zend_Validate_GreaterThan(array('min' => 0.90))); $element->addFilter(new Zend_Filter_LocalizedToNormalized()); // ! $form->addElement($element); //input values $data = array('val' => "0,92"); var_dump($form->isValid($data)); //true
Uwagi
Warto rozważyć także używanie filtra odwrotnego Zend_Filter_NormalizedToLocalized
w momencie wyświetlania danych w formularzu. Warto zwrócić uwagę na fakt, że filtrów i walidatorów używać można także bez formularza – ww. filtr przydać może się przy zapisywaniu danych w DB.