我有这个示例数组。
$data = new stdClass();
$data->foo = [
'foo1' => &$data,
'foo2' => 23,
];
$data->bar = new stdClass();
$data->nar->object = [
'bar1' => &$data->bar,
'bar2' => 43,
];
我想将其解析为:
$data = new stdClass();
$data->foo = [
'foo1' => "RECURSION DETECTED",
'foo2' => 23,
];
$data->bar = new stdClass();
$data->nar->object = [
'bar1' => "RECURSION DETECTED",
'bar2' => 43,
];
我需要它,因为 json_encode
无法在检测到递归时对数据进行编码。
我以不同的方式尝试了很多次,我做了很多研究,但我没有找到任何真正能帮助我的东西。
我最后一次尝试是:
function _stack(&$object, &$stack = [], $key = 'original')
{
if (isObjectOrArray($object)) {
if (!in_array($object, $stack, true)) {
if (is_object($object)) {
$stack[$key] = &$object;
}
foreach ($object as $key => &$value) {
_stack($value, $stack, $key);
}
}
}
return $stack;
}
function _remove($object, $stack, $objectO = false, $key = 'original')
{
/**
* @var $objectO false | object
*/
if (!$objectO) {
$objectO = $object;
}
if (isObjectOrArray($object)) {
foreach ($object as $prop => $value) {
if (is_object($objectO)) {
if (in_array($object->{$prop}, $stack, true) && $prop !== $key) {
$objectO->{$prop} = "RECURSION DETECTED";
} else {
$objectO->{$prop} = _remove($object->{$prop}, $stack, $objectO->{$prop}, $prop);
}
} else {
if (in_array($object[$prop], $stack, true) && $prop !== $key) {
$objectO[$prop] = "RECURSION DETECTED";
} else {
$objectO[$prop] = _remove($object[$prop], $stack, $objectO[$prop], $prop);
}
}
}
}
return $objectO;
}
首先,我用原始对象(不是引用/指针)创建了一个堆栈。 key 以递归方式传递给函数,在函数本身内部,所以我确切地知道递归在哪里与原始对象相遇。我需要它,这样我才能知道指针是什么以及原始对象是什么。
创建堆栈后我运行相同的循环,但是 foreach 语句中的当前值是一个对象并且他在堆栈中并且当前键与传递给函数调用的当前键不同,引用/指针被破坏。
Array
(
[foo1] => RECURSION DETECTED
[foo2] => 23
)
但是在所有函数调用结束时我只得到:
RECURSION DETECTED
最佳答案
我仍在寻找另一种方式,因为这很有趣,但很容易替换序列化字符串中的引用指针,然后将其反序列化:
$data = unserialize(preg_replace('/R:\d+/', 's:18:"RECURSION DETECTED"', serialize($data)));
PHP >= 7.3.0 的另一个选项是导出并强制它中断引用。 var_export
会提示递归,但它会很高兴地显示它,并将引用替换为 NULL
。 var_export
有第二个参数来返回输出而不是显示,但这不适用于递归,所以我缓冲并捕获了输出。
ob_start();
@var_export($data);
$var = ob_get_clean();
eval("\$data = $var;");
对于 PHP < 7.3.0,您可以将上述代码与您自己实现 __set_state
而不是 stdClass
的类一起使用:
class myClass {
public static function __set_state($array) {
$o = new self;
foreach($array as $key => $val) {
$o->$key = $val;
}
return $o;
}
}
$data = new myClass();
关于php - 如何删除对象或数组中的递归?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55069945/