尝试解决“不可能”的问题总是很有趣!
这是一个函数,如果递归发生在顶层,它将检测递归数组:
function is_recursive(array &$array) {
static $uniqueObject;
if (!$uniqueObject) {
$uniqueObject = new stdClass;
}
foreach ($array as &$item) {
if (!is_array($item)) {
continue;
}
$item[] = $uniqueObject;
$isRecursive = end($array) === $uniqueObject;
array_pop($item);
if ($isRecursive) {
return true;
}
}
return false;
}
看到它在行动。
在任何级别检测递归显然会更加棘手,但我认为我们可以同意这似乎是可行的。
更新
这是检测任何级别的递归的递归(双关语并非有意但令人愉快)解决方案:
function is_recursive(array &$array, array &$alreadySeen = array()) {
static $uniqueObject;
if (!$uniqueObject) {
$uniqueObject = new stdClass;
}
$alreadySeen[] = &$array;
foreach ($array as &$item) {
if (!is_array($item)) {
continue;
}
$item[] = $uniqueObject;
$recursionDetected = false;
foreach ($alreadySeen as $candidate) {
if (end($candidate) === $uniqueObject) {
$recursionDetected = true;
break;
}
}
array_pop($item);
if ($recursionDetected || is_recursive($item, $alreadySeen)) {
return true;
}
}
return false;
}
看到它在行动。
当然,这也可以通过手动保留堆栈来编写为使用迭代而不是递归,这在递归级别非常大的情况下会有所帮助。