ZF-4000: Zend_Validate_Float always fails in localized environments
Description
First: Zend_Framework provides a powerful Zend_Locale. In my optionion Zend_Locale should be used with Zend_Validate_Float instead of localeconv().
Second: Zend_Validate_Float always failes when PHP is localized.
In method isValid(), the float value is first converted to an english value:
$valueFiltered = str_replace($locale['thousands_sep'], '', $valueString); $valueFiltered = str_replace($locale['decimal_point'], '.', $valueFiltered);
So $valueFiltered always ends up with a value like "0.3" (also in localized environments).
But now the problem is that floatval is localized itself; floatval(0.3) will give 0,3 in a german environment. Finally, stringval(floatval(0.3)) gives 0,3. And exactly this string is compared to the original $valueFiltered:
if (strval(floatval($valueFiltered)) != $valueFiltered) {
So this if-statement will always fail.
I would recommend to use a class like this:
class Zend_Validate_Float extends Zend_Validate_Abstract {
const NOT_FLOAT = 'notFloat';
protected $_messageTemplates = array(
self::NOT_FLOAT => "'%value%' does not appear to be a float"
);
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
$locale = Zend_Registry::get('Zend_Locale');
if(!$locale) {
$locale = new Zend_Locale();
}
if(!Zend_Locale_Format::isFloat($value, array('locale' => $locale))) {
$this->_error();
return false;
}
return true;
}
}
Comments
Posted by Thomas Weidner (thomas) on 2008-08-19T11:18:14.000+0000
Duplicates ZF-3423
Posted by Thomas Weidner (thomas) on 2008-11-29T11:58:28.000+0000
This solution:
Posted by Sven Franke (snef) on 2008-11-29T12:24:00.000+0000
Zend_Validator_Date is implementing an optional Zend_Locale, maybe to create something like that (to keep it in line).
Posted by Thomas Weidner (thomas) on 2008-12-19T04:03:19.000+0000
New feature added with r13372