ZF-5030: Failure to parse Zend_Locale objects is Zend_Locale::isLocale

Description

After upgrading to Zend Framework 1.7 (from 1.6.2) Zend_Date objects started throwing exceptions on construction with an error "Given locale (Object id #1) does not exist" when they are passed a Zend_Locale object (They construct fine if given a locale string [eg. en_AU])

This has been traced back to Zend_Locale::_prepareLocale() where it evaluates the Zend_Locale object passed (valid) as a string and converts it into the string "Object id #1".

Test code:


<?php

set_include_path('/opt/library');
require_once '/opt/library/Zend/Locale.php';
require_once '/opt/library/Zend/Date.php';

$locale1 = new Zend_Locale('en_AU');

//This Works
if (!Zend_Locale::isLocale('en_AU', true, false))
  echo "Zend Locale failed to identify local string as valid";
//This doesn't
if (!Zend_Locale::isLocale($locale1, true, false))
  echo "Zend Locale failed to idenfiy a Zend_Local object as valid";

$date = new Zend_Date();
$date->setLocale($locale1); //Throws Exception

Output:

 
PHP Notice:  Object of class Zend_Locale to string conversion in /opt/library/Zend/Locale.php on line 885
Zend Locale failed to idenfiy a Zend_Local object as validPHP Notice:  Object of class Zend_Locale to string conversion in /opt/library/Zend/Locale.php on line 885
PHP Notice:  Object of class Zend_Locale to string conversion in /opt/library/Zend/Locale.php on line 885
PHP Fatal error:  Uncaught exception 'Zend_Date_Exception' with message 'Given locale (Object id #1) does not exist' in /opt/library/Zend/Date.php:4517
Stack trace:
#0 /tmp/test.php(17): Zend_Date->setLocale(Object(Zend_Locale))
#1 {main}
  thrown in /opt/library/Zend/Date.php on line 4517

Comments

Actually this looks like a issue with the string conversion issue. When the locale is converted to a string with (string) $locale, this is where the "Object id #1" appears.

This is with php version 1.5.6 (RHEL5 package). Looking at the PHP documentation there are differences in how the __toString magic method is applied between 5.1 and 5.2 (http://au.php.net/oop5.magic) could this be related.

Test code:


<?php

set_include_path('/opt/library');
require_once '/opt/library/Zend/Locale.php';
require_once '/opt/library/Zend/Date.php';

echo "Test 1\n";
$locale1 = new Zend_Locale('en_AU');
print_r($locale1);
echo "\n";

echo "Test 2\n";
$convert = (string) $locale1;
echo $convert;
echo "\n";

"Test 3\n";
$convert2 = $locale1->toString();
echo $convert2;
echo "\n";

Result:

Test 1
Zend_Locale Object
(
    [_locale:protected] => en_AU
)

Test 2
Object id #1
Test 3
en_AU

Sorry, but the minimum requirements for ZF are 5.2.4 and not 1.5.6 !

http://framework.zend.com/manual/en/… states that 1.5.4 is the minimum requirement with recommended 5.2.3.

5.1.6 is the version shipped with Redhat Enterprise Linux 5.2 (latest version). I would think that Zend Framework is aiming to support the latest in Enterprise releases?!

No... PHP 1.5.4 is not supported by ZF.

According to manual: A.1. PHP Version Zend recommends PHP 5.2.3 or higher for critical security and performance enhancements, although Zend Framework requires only PHP 5.1.4 or later.

But, and this is emminent, ZF can not solve problems of php itself. PHP 5.1.4, 5.2.1 and 5.2.5, which are the versions I am testing against, behave correct. You could run unittests to check this. With such a problem within PHP also other classes will not work.

Can you please run the two tests I posted above and let me know if you get the same or different results with your v5.1.4? Looking into the issue further there are enough documented cases that the magic method does not work in any version of 5.1 and you should use $object->__toString() instead of (String)$object

If 5.1.4 is indeed the minimum requirement then should the components using the magic method be modified to call the __toString function directly? Otherwise the doco needs to be updated that parts of 1.7 won't work on php 5.1 (eg Redhat 5 distributed versions). I know the Framework can't fix problems with php (only working around them) but there is a valid method that works across these versions.

Should I move this to the email list for further discussion?

I added a forth test, which you have missed:


var_dump(Zend_Locale::isLocale($locale1));

This are my results:


PHP Version:5.1.4
Test 1
Zend_Locale Object
(
    [_locale:protected] => en_AU
)

Test 2
Object id #1
Test 3
en_AU
Test 3
bool(true)

and


PHP Version:5.2.5
Test 1
Zend_Locale Object
(
    [_locale:protected] => en_AU
)

Test 2
en_AU
Test 3
en_AU
Test 3
boolean true

And these are my problems... wether in 5.1.4 nor in 5.2.5 I can reproduce this.

You did reproduced this in your 5.1.4 PHP installation. Test 2 outputted "Object id #1" which shows the __toString magic method didn't fire.

This issue was not about a PHP 5.1.4 problem, this issue was about this failing code:


if (!Zend_Locale::isLocale($locale1, true, false))
  echo "Zend Locale failed to idenfiy a Zend_Local object as valid";

which I tested with the 4th test I added.... and both PHP versions return true.

Under 5.1.4 with (bool) true and under 5.2.5 with boolean true. But, and this is what you originally issued, both return true when calling isValid running actual trunk.

I have this problem on 5.1.6 too (CentOS) And all works good on 5.2(Debian Stable)