如何在递归解析关联数组时检查PHP中的循环引用?
作者:互联网
我用循环引用创建了这个数组:
$arr = array(1 => 'one', 2 => 'two');
$arr[3] = &$arr;
我有一个函数递归打印出数组中的值,但我真的无法解决创建循环引用检查的问题.你怎么能这样做?
我打印数组的当前函数复制如下.我没有包括我在进行循环引用检查时所做的各种尝试.它们主要围绕一种策略来维护已经为每个递归分支打印的$items项目.这是因为我仍然希望允许打印重复值,如果它是正在解析的当前数组的父节点,则不打印值.
我遇到的问题是如何在这个$seen变量中添加引用而不是数组副本.但如果有效,我会很高兴再次使用其他策略.
function HTMLStringify($arr)
{
if(is_array($arr)){
$html = '<ul>';
foreach ($arr as $key => $value) {
$html .= '<li>' . $key;
if(is_array($value)){
//Conspicuously missing is a circular reference check,
//causing infinite recursion. After a few failed attempts
//at checking for this (e.g. discovering that array_push doesn't take references)
//I have left it for further study.
//(After all, Javascript's JSON.stringify() doesn't check for circular references)
//TODO: Check for circular references
$html .= HTMLStringify($value, $seen);
}
elseif(is_numeric($value) || is_string($value) || is_null($value))
{
$html .= ' = ' . $value;
}
else
{
$html .= ' [couldn\'t parse ' . gettype($value) . ']';
}
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}
else
{
return null;
}
}
解决方法:
使用the answer linked by Ryan Vincent中严格的in_array检查,您的代码的改编版本如下所示:
function HTMLStringify($arr, array $seen = array()) {
if (is_array($arr)) {
$seen[] = $arr;
$html = '<ul>';
foreach ($arr as $key => $value) {
$html .= '<li>' . $key;
if (is_array($value)) {
if (in_array($value, $seen, true)) {
// Deal with recursion in your own way here
$html .= ' [RECURSION]';
} else {
$html .= HTMLStringify($value, $seen);
}
} elseif (is_numeric($value) || is_string($value) || is_null($value)) {
$html .= ' = ' . $value;
} else {
$html .= ' [couldn\'t parse ' . gettype($value) . ']';
}
$html .= '</li>';
}
return $html . '</ul>';
} else {
return null;
}
}
$arr = array(1 => 'one', 2 => 'two');
$arr[3] = &$arr;
echo HTMLStringify($arr);
Comparing across a number of PHP versions,看起来这适用于PHP 5.3.15和PHP 5.4.5.
标签:php,arrays,recursion,circular-reference 来源: https://codeday.me/bug/20190708/1404836.html