Zend Framework and locales

Last night I spent a couple of hours with Zend Framework and especially Zend_Form. I discovered, and now also reported as ZF-6175, a bug in Zend_Validate_Float when using a locale with a decimal point other than “.”. There are unit tests but none that test Zend_Validate_Float under a different locale.

It is important to know that floats are actually locale aware in PHP. I’m not sure if that have always been the case. The below code will actually output 10,5 as Swedish use “,” as decimal point.

setlocale(LC_ALL, 'sv_SE.UTF-8');
echo 10.5;

The test in Zend_Validate_Float looked like

$locale = localeconv();

$valueFiltered = str_replace($locale['thousands_sep'], '', $valueString);
$valueFiltered = str_replace($locale['decimal_point'], '.', $valueFiltered);

if (strval(floatval($valueFiltered)) != $valueFiltered) {
  $this->_error();
  return false;
}

Under the Swedish locale mentioned above this will result in a comparison between two strings; “10,5″ and “10.5″.

I have proposed the following solution.

$locale = localeconv();

$valueFiltered = str_replace($locale['thousands_sep'], '', $valueString);
$valueFiltered = str_replace($locale['decimal_point'], '.', $valueFiltered);

list($num, $dec) = explode('.', $valueFiltered);
if (strval(intval($num)) != $num || strval(intval($dec)) != $dec) {
  $this->_error();
  return false;
}

But I just realized that it can be further simplified.

$locale = localeconv();

$valueFiltered = str_replace($locale['thousands_sep'], '', $valueString);

list($num, $dec) = explode($locale['decimal_point'], $valueFiltered);
if (strval(intval($num)) != $num || strval(intval($dec)) != $dec) {
  $this->_error();
  return false;
}
Tagged with: , ,
Posted in PHP
3 comments on “Zend Framework and locales
  1. Lukas says:

    I think its hopeless to ask libraries to play nice with set_locale(). Just wait for PHP6, until then either dont use set_locale() or if you must do it in your own code and revert it back to standard the second you call other peoples code.

  2. Danne says:

    Hopeless? Well if no one reports errors the of course no one will fix them…

    And why I would wait for PHP 6 I don’t know. This particular problem is in Zend Framework. Not PHP.

  3. Gabriel says:

    Aaah, this behavior has bitten me too! I was in a hurry to fix it, so my “fix” was to remove Zend_Locale and use str_replace and number_format instead (It’s an app that will never have another locale than de_DE). Great to see that it is indeed a bug und not my misunderstanding of I18N.

    @Lucas If you can wait for PHP 6 that’s a great luxury I don’t have. I have customers that want to have apps to display their prices NOW. Not using set_locale is not an option because of encoding requirements. Reverting to the default locale would be ok (but would produce long code with each formatting and conversion of a number taking 3 lines instead of 1), but if this patch fixes the behavior in a future-proof way I am very thankful.

1 Pings/Trackbacks for "Zend Framework and locales"
  1. [...] a new post to his blog Danne Lundqvist take a look at using locales in the Zend Framework and a [...]

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>