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

That was an oversight. Thanks for pointing it out.

Can you add some test code that logs a message where the UTF-8 test does not display properly?

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?

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.

Waiting for resolution of ZF-4053.

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


"* RECURSION ([Class Name]) *"

2) Zend_Json_Encoder adds class hint information to the JSON string


{"__className":"[Class Name]", ... }

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.

The request is for UTF-8 character support. To accomplish this issue ZF-4054 must be resolved.