ZF-6786: When encoding an non-associative array with a Zend_Json_Expr the result is the magic key: ____0

Description

This code:

$values = array();
$values['plugins'] = 
  array(
    new Zend_Json_Expr(
      'new Ext.ux.PageSizePlugin()'
    )
  );

return Zend_Json::encode(   $values,
                    false,
                    array('enableJsonExprFinder' => true));

returns



what is obviously wrong.

I created a fix in zend/Json.php for this case. line 135:

if ($key == '') { $encodedResult = str_replace( '"' . $magicKey . '"', $value, $encodedResult ); } else { $encodedResult = str_replace( '"' . $key . '":"' . $magicKey . '"', '"' . $key . '":' . $value, $encodedResult ); }```

Comments

patches Json.php file

Assigning to Oscar.

I encountered this behaviour too this week... confirmed ;)

working on it!

Ok this is what I get:

1.- In the pre-encoding call to _recursiveJsonExprFinder function, when a non-assoc array is passed, the "key" is setted to "null". This happen because the function Zend_Json_Encoder::encodeUnicodeString returns null when an integer is passed as param.

2.- Because of that, the after encoding replacing fails.

It could be fixed with the next patch mentioned before:


if ($key == '') {
    $encodedResult = str_replace(
        '"' . $magicKey . '"',
        $value,
        $encodedResult
    );
} else {
    $encodedResult = str_replace(
        '"' . $key . '":"' . $magicKey . '"',
        '"' . $key . '":' . $value,
        $encodedResult
    );
}

but it nis not neccessary because with the actual code "key" is not neccesary anymore. It is enough replacing "magicKey" by its correspondant "value":


        //only do post-proccessing to revert back the Zend_Json_Expr if any.
        if (count($javascriptExpressions) > 0) {
            $count = count($javascriptExpressions);
            for($i = 0; $i < $count; $i++) {
                //$key      = $javascriptExpressions[$i]['key'];//key is not neccesary
                $magicKey = $javascriptExpressions[$i]['magicKey'];
                $value    = $javascriptExpressions[$i]['value'];

                $encodedResult = str_replace(
                //instead of replacing "key:magicKey", we replace directly magicKey by value because "key" never changes.
                // '"' . $key . '":"' . $magicKey . '"',
                //'"' . $key . '":' . $value,
               
                    '"' . $magicKey . '"',
                    $value,
                    $encodedResult
                );
            }
        }

Anyway, to avoid unneccesary function calls when the "currentKey" is an integer (non associative array) I changed also this code:


  "magicKey" =>  Zend_Json_Encoder::encodeUnicodeString($magicKey),

for this:


  "magicKey" => (is_int($currentKey)) ? $magicKey : Zend_Json_Encoder::encodeUnicodeString($magicKey),

I have re-code "Zend_Json" and added a test to JsonTest.php to testing this bug. Test is OK now.

Re-coded Zend_Json to fix issue, and avoid unnecessary calls to Zend_Json_Encoder::encodeUnicodeString(); comments on changes included (clean old code and comments in final version).