What is the best way to check if an array is recursive in PHP ?
Given the following code:
It's always fun to try solving "impossible" problems!
Here's a function that will detect recursive arrays if the recursion happens at the top level:
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;
}
See it in action.
Detecting recursion at any level would obviously be more tricky, but I think we can agree that it seems doable.
And here is the recursive (pun not intended but enjoyable nonetheless) solution that detects recursion at any level:
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;
}
See it in action.
Of course this can also be written to work with iteration instead of recursion by keeping a stack manually, which would help in cases where a very large recursion level is a problem.