Issues

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

Duplicates ZF-3423

This solution:

  • does not work when no application locale is given
  • does not work when the given locale is no locale
  • does not allow to override the application locale with a manual locale

Zend_Validator_Date is implementing an optional Zend_Locale, maybe to create something like that (to keep it in line).

New feature added with r13372