ZF-4040: Zend_Wildfire_Protocol_JsonStream->_encode using bad internal Zend_Json encoder
Description
h3.The problem
/**
* Encodes messages into the Wildfire JSON Stream Communication Protocol.
*/
class Zend_Wildfire_Protocol_JsonStream
{ ...
// Use the JSON encoding scheme for the value specified
protected function _encode($value)
{
return Zend_Json_Encoder::encode($value);
}
...
}
Why there's Zend_Json{color:red}_Encoder{color} here in place of Zend_Json?! So I've got my UTF-8 debug output corrupted in FirePHP because of that.
Removing _Encoder lets Zend_Json::encode method to choose appropriate JSON encoding method according to PHP's json_encode function availability. After that my UTF-8 text displays correctly.
h3.Test code with string in russian:
// in bootstrap
$logger = new Zend_Log(new Zend_Log_Writer_Firebug());
Zend_Registry::set('log', $logger);
// in controller
Zend_Registry::get('log')->debug('Some debug text in english is OK'); // that's OK
Zend_Registry::get('log')->debug('Отладочный русский текст искажается!'); // that's corrupted
May be there's a reason to file another bug on Zend_Json_Encoder's _encodeString method? By the way, give a glance at FirePHP's main standalone class "FirePHP.class.php" and its "json_encode" method. It actually does the job right! May be ZJE->_encodeString should follow this example?
Comments
Posted by Christoph Dorn (cadorn) on 2008-08-22T18:01:48.000+0000
That was an oversight. Thanks for pointing it out.
Posted by Christoph Dorn (cadorn) on 2008-08-22T23:22:02.000+0000
Can you add some test code that logs a message where the UTF-8 test does not display properly?
Posted by Christoph Dorn (cadorn) on 2008-08-24T12:12:35.000+0000
I have looked into json_encode and Zend_Json_Encoder in more detail.
While json_encode detects recursion, it does not silently truncate the resulting JSON string but instead throws an exception. Zend_Json_Encoder on the other hand truncates it and still returns a valid JSON string.
It is very common to have cyclical relationships in your object graph which should get JSON encoded and sent to the client in a truncated fashion.
The best solution for the encoding would be to try json_encode first and if it fails fall back to Zend_Json_Encoder. This would mean that UTF8 encoded messages cannot contain cyclical object relationships.
The alternative would be to add UTF8 encoding support to Zend_Json_Encoder which would be great, but not practical as an immediate fix for this issue.
So would the fallback approach work for now until Zend_Json_Encoder supports UTF8 characters?
Posted by Christoph Dorn (cadorn) on 2008-08-24T14:40:13.000+0000
Looks like my tests were not correct.
json_encode() nor Zend_Json_Encoder silently truncate cyclical relationships.
I'll have to submit a patch for Zend_Json_Encoder to silence the cyclical exception.
Posted by Christoph Dorn (cadorn) on 2008-08-24T14:49:24.000+0000
Waiting for resolution of ZF-4053.
Posted by Christoph Dorn (cadorn) on 2008-08-24T17:30:40.000+0000
I have decided to stick with Zend_Json_Encoder and not try json_encode() first for the following reasons:
1) Zend_Json_Encoder adds more detailed information (i.e. the class name) when it trims cyclical relationships
2) Zend_Json_Encoder adds class hint information to the JSON string
Zend_Wildfire_Protocol_JsonStream will support UTF-8 characters as soon as Zend_Json_Encoder supports them. See issue ZF-4054.
To speed up general support for UTF-8 characters, please lobby for ZF-4054.
Posted by Christoph Dorn (cadorn) on 2008-08-24T17:32:14.000+0000
The request is for UTF-8 character support. To accomplish this issue ZF-4054 must be resolved.