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.
Kanał ATOM

Od jakiegoś czasu borykałem się z problemem dlaczego czasami zapisywane do bazy danych zserializowane dane są „obcinane. Poszukiwania, googlanie niewiele pomagało aż a końcu trafiłem gdzieś na informację że problemem może być znak NULL (0×00) w którym PHPowe serialize się lubuje