我已经使用此功能“修复”对象有一段时间了——它似乎在从私有对象和受保护对象转换为“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>";
正如对该问题的评论中所述,您应该小心使用诸如爆破“私人”或“受保护”数据之类的东西可能是一件坏事。但是,在某些情况下,开发人员只是将所有内容都设置为“私有”或“受保护”(即使它确实不应该是……)——在这些情况下,此功能是救命稻草!