Is there a way to find out how "deep" a PHP array is?

Viewed 52296

A PHP array can have arrays for its elements. And those arrays can have arrays and so on and so forth. Is there a way to find out the maximum nesting that exists in a PHP array? An example would be a function that returns 1 if the initial array does not have arrays as elements, 2 if at least one element is an array, and so on.

20 Answers

Here's another alternative that avoids the problem Kent Fredric pointed out. It gives print_r() the task of checking for infinite recursion (which it does well) and uses the indentation in the output to find the depth of the array.

function array_depth($array) {
    $max_indentation = 1;

    $array_str = print_r($array, true);
    $lines = explode("\n", $array_str);

    foreach ($lines as $line) {
        $indentation = (strlen($line) - strlen(ltrim($line))) / 4;

        if ($indentation > $max_indentation) {
            $max_indentation = $indentation;
        }
    }

    return ceil(($max_indentation - 1) / 2) + 1;
}

This should do it:

<?php

function array_depth(array $array) {
    $max_depth = 1;

    foreach ($array as $value) {
        if (is_array($value)) {
            $depth = array_depth($value) + 1;

            if ($depth > $max_depth) {
                $max_depth = $depth;
            }
        }
    }

    return $max_depth;
}

?>

Edit: Tested it very quickly and it appears to work.

Beware of the examples that just do it recursively.

Php can create arrays with references to other places in that array, and can contain objects with likewise recursive referencing, and any purely recursive algorithm could be considered in such a case a DANGEROUSLY naive one, in that it will overflow stack depth recursing, and never terminate.

( well, it will terminate when it exceeds stack depth, and at that point your program will fatally terminate, not what I think you want )

In past, I have tried serialise -> replacing reference markers with strings -> deserialise for my needs, ( Often debugging backtraces with loads of recursive references in them ) which seems to work OK, you get holes everywhere, but it works for that task.

For your task, if you find your array/structure has recursive references cropping up in it, you may want to take a look at the user contributed comments here: http://php.net/manual/en/language.references.spot.php

and then somehow find a way to count the depth of a recursive path.

You may need to get out your CS books on algorithms and hit up these babies:

( Sorry for being so brief, but delving into graph theory is a bit more than suited for this format ;) )

This one seems to work fine for me

<?php
function array_depth(array $array)
{
    $depth = 1;
    foreach ($array as $value) {
        if (is_array($value)) {
            $depth += array_depth($value);
            break;
        }
    }

    return $depth;
}

I don't think there's anything built in. A simple recursive function could easily find out though.

I would use the following code:

function maxDepth($array) {
    $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($array), \RecursiveIteratorIterator::CHILD_FIRST);
    $iterator->rewind();
    $maxDepth = 0;
    foreach ($iterator as $k => $v) {
        $depth = $iterator->getDepth();
        if ($depth > $maxDepth) {
            $maxDepth = $depth;
        }
    }
    return $maxDepth;
}
//Get the dimension or depth of an array
function array_depth($arr)
{
    if (!is_array($arr)) return 0;
    if (empty($arr))     return 1;
    return max(array_map(__FUNCTION__,$arr))+1;
}

in my solution, I evaluate dimension of ARRAY(), not contents/values:

function Dim_Ar($A, $i){
    if(!is_array($A))return 0;
    $t[] = 1;
    foreach($A AS $e)if(is_array($e))$t[] = Dim_Ar($e, ++ $i) + 1;
    return max($t);
    }

$Q = ARRAY();                                                                               // dimension one
$Q = ARRAY(1);                                                                          // dimension one
$Q = ARRAY(ARRAY(ARRAY()), ARRAY(1, 1, 1));                 // dimension is two
$Q = ARRAY(ARRAY());                                                                // dimension is two
$Q = ARRAY(1, 1, 1, ARRAY(), ARRAY(), ARRAY(1));        // dimension is two
$Q = ARRAY(1, 2, 3, ARRAY(ARRAY(1, 1, 1)));                 // dimension is two
$Q = ARRAY(ARRAY(ARRAY()), ARRAY());                                // dimension is three
$Q = ARRAY(ARRAY(ARRAY()), ARRAY());                                // dimension three
$Q = ARRAY(ARRAY(ARRAY()), ARRAY(ARRAY()));                 // dimension is three
$Q = ARRAY('1', '2', '3', ARRAY('Q', 'W'), ARRAY('Q', 'W'), ARRAY('Q', 'W'), ARRAY('Q', 'W'), 'pol, y juan', 'sam, y som', '1', '2', 'OPTIONS1' => ARRAY('1', '2', '9'), 'OOO' => ARRAY('1', '2', '9'), 'OPTIONS3' => ARRAY('1', '2', '9', '1', '2', '9', '1', '2', '9', '1', '2', '9', '1', '2', '9'), '3', ARRAY('Q', 'W'), 'OPTIONS2' => ARRAY('1', '2'));
$Q = ARRAY('1', '2', '3', '', ARRAY('Q, sam', 'W', '', '0'), 'ppppppol, y juan', 'sam, y som', '1', '2', 'OPTIONS1' => ARRAY('1', '2', 'ss, zz'), '3', 'PP' => ARRAY('Q', 'WWW', 'Q', 'BMW'), ARRAY('Q', 'YYWW'), 'OPTIONS2' => ARRAY('1', '2', '9'), ARRAY('1', '2', '3'), '33', '33', '33', ARRAY('1', '2', '3', ARRAY(1, 2)));

echo Dim_Ar($Q, 0);

for me is speed, and low complex

Related