1

在 Chrome PHP 中,对象在发送到响应头之前通过 json_encode 转换为 json。这不适用于包含递归的对象 - 调用json_last_error_msg()recursion detected并且输出为空。有没有办法防止这种情况,比如削减递归之类的?

 protected function _encode($data) {
        $ret = base64_encode(utf8_encode($json = json_encode($data)));
        if (!$json) {
            print_r(json_last_error_msg()); //says 'recursion detected, when recursion found' 
            return "";
        }
        return $ret;
}
4

1 回答 1

1

我已经使用此功能“修复”对象有一段时间了——它似乎在从私有对象和受保护对象转换为“stdClass”方面做得很好,然后我可以在其中查看和使用数据。

function fix_object( $object ) {
    $dump = serialize( $object );
  //  print_r($dump); echo "<hr>";
    $dump = str_replace('s:6:"series";r:1;','s:6:"series";s:6:"series";',$dump);
   // print_r($dump); echo "<hr>";
    $dump = preg_replace( '/^O:\d+:"[^"]++"/', 'O:8:"stdClass"', $dump );
    $dump = preg_replace_callback( '/:\d+:"\0.*?\0([^"]+)"/', function($matches){
                return ":" . strlen( $matches[1] ) . ":\"" . $matches[1] . "\"";}, $dump );
    return unserialize( $dump );
}

请参阅 'print_r($dump);' 之间的行 行 - 这是您唯一需要为自己的对象更改的行(我将 'hr's 放在转储周围以提供更多间距......)

就我而言,如您所见,我发现“系列”上有“r:1”,这导致 json_encode 给出递归检测错误。

通过查看序列化转储,我发现并用字符串替换了它(你可以放任何不破坏 json 的东西,但要小心!)

由于不需要递归的部分(已经在对象中......),我用什么替换它并不重要。

最终结果是一个非常好的、无错误的 json_encode!

 echo "json series = " . json_encode(fix_object( $origObject)) . "<br>";

正如对该问题的评论中所述,您应该小心使用诸如爆破“私人”或“受保护”数据之类的东西可能是一件坏事。但是,在某些情况下,开发人员只是将所有内容都设置为“私有”或“受保护”(即使它确实不应该是……)——在这些情况下,此功能是救命稻草!

于 2018-04-27T22:24:37.000 回答