PHP中无限嵌套数组的确定

PHP中无限嵌套数组的确定,php,arrays,recursion,Php,Arrays,Recursion,所以 在PHP中确定数组中的递归有一个问题。假设我有一个动态生成的数组,它最终可以如下所示: $rgData = [ ['foo', 'bar', $rgTemp=[7, 31, true]], [-5, &$rgData, 'baz'] ]; (此处的变量链接是动态提供的,可能引用数组本身)。另一个样本: $rgData = [ ['foo', 'bar', $rgTemp=[7, 31, true]], [-5, &$rgTemp, 'baz'] ]

所以

在PHP中确定数组中的递归有一个问题。假设我有一个动态生成的数组,它最终可以如下所示:

$rgData = [
   ['foo', 'bar', $rgTemp=[7, 31, true]],
   [-5, &$rgData, 'baz']
];
(此处的变量链接是动态提供的,可能引用数组本身)。另一个样本:

$rgData = [
   ['foo', 'bar', $rgTemp=[7, 31, true]],
   [-5, &$rgTemp, 'baz']
]; 
两个数组中都有一些引用,但第二个数组看起来不错,因为它的引用没有循环。后来,由于我的逻辑,我不得不通过递归函数处理数组(类似于
array\u walk\u recursive
)——当然,在上面的第一个示例中,由于无限嵌套数组递归,我得到了致命错误

我的问题是-如何确定数组是否具有无限递归。请注意,这个问题比从数组内部到自身的简单搜索链接更复杂,因为我们可以有如下内容:

$rgOne = [
   ['foo', 'bar'],
   ['baz']
];
$rgTwo = [6, 'test', &$rgOne];
$rgOne[1][] = &$rgTwo;
i、 更复杂的递归。我发现PHP可以在
var_dump
和类似的函数中以某种方式解决这个问题,例如,第三个示例的dump如下所示:

array(2) { [0]=> array(2) { [0]=> string(3) "foo" [1]=> string(3) "bar" } [1]=> array(2) { [0]=> string(3) "baz" [1]=> &array(3) { [0]=> int(6) [1]=> string(4) "test" [2]=> &array(2) { [0]=> array(2) { [0]=> string(3) "foo" [1]=> string(3) "bar" } [1]=> *RECURSION* } } } } 但没有成功(我知道为什么——这种比较是无效的)。我现在唯一的想法就是做一些奇怪的事情,比如:

function isLooped(&$rgData)
{
   $rgTemp  = @var_export($rgData, 1);
   return preg_match('/circular references/i', error_get_last()['message']);
}
但这是令人悲哀的,因为我至少需要将阵列数据复制到一些临时存储中(而且,所有这些看起来都像是小故障,不是一个合适的解决方案)。那么,可能有一些关于如何以正常的方式做到这一点的想法吗


更新:我在数组中找到了一个via键,然后在递归循环中查找它。这比
var.*
函数好得多,但仍然不是我想要的。有没有一种方法可以不用
var.*
函数或更改原始数组就可以做到这一点?

问题在于PHP没有一种机制来告诉您两个变量是否引用相同的zval(表示实际持有数据的内部数据类型)。这就排除了跟踪您已经遍历的变量作为解决方案的可能性


不幸的是,如果没有这个特性或修改元素(pin方法),除了
var\u dump()
print\u r()
hacks之外,就不可能检测递归数据结构。

问题是PHP没有一种机制来告诉您两个变量是否引用相同的zval(表示实际持有数据的内部数据类型)。这样就排除了跟踪已遍历的变量作为解决方案的可能性


不幸的是,如果没有此功能或修改元素(pin方法),则除了
var\u dump()
print\u r()之外,无法检测递归数据结构
hacks.

这与您在@VladimirHraban问的问题类似,我不确定-因为我提到我不想依赖
print\u r
/
var\u dump
e.t.c-函数。另一个解决方案是更改数组本身(然后再次检查)-这看起来更好,但仍然不足以回答:是否有可能以正常方式进行(否定回答对我也有好处-我知道改变架构本身更简单)。谢谢!这可能与您在@VladimirHraban问的问题类似,我不确定-因为我已经提到我不想依赖
print\u r
/
var\u dump
e.t.c-函数。另一个解决方案是更改数组本身(然后再次检查)-这看起来更好,但仍然不足以回答:是否有可能以正常方式进行(否定回答对我也有好处-我知道改变架构本身更简单)。谢谢!可能重复我正在寻找的答案(即“不,在这种情况下不能这样做”)。谢谢。突然:p我的问题只有一个得到了肯定的解决:p(以及我自己实现的解决方案)因此,似乎我正在寻找的答案(即“不,在这种情况下无法实现”)。谢谢。突然:p我的问题只有一个得到了肯定的解决:p(以及我自己实现的解决方案)
function isLooped(&$rgData)
{
   $rgTemp  = @var_export($rgData, 1);
   return preg_match('/circular references/i', error_get_last()['message']);
}