rap-2-h
rap-2-h

Reputation: 31998

How to get the current recursion level in a PHP function

How can I get the current recursion level in a PHP function?

I mean, is there any "magical" (or eventually normal) function like the following?

function doSomething($things) {
    if (is_array($things)) {
        foreach ($things as $thing) {
            doSomething($thing);
        }
    } else {
        // This is what I want:
        echo current_recursion_level();
    }
}

I know I can use another function argument ($level in this example):

function doSomething($things, $level = 0) {
    if (is_array($things)) {
        foreach ($things as $thing) {
            $level++;
            doSomething($thing, $level);
        }
    } else {
        echo $level;
    }
}

But I want to know if there is a built-in function (or trick) to do that. Maybe something with debug_backtrace(), but it does not seem to be a simple or quick solution.

I did not found this information. Maybe it simply does not exists...

Upvotes: 9

Views: 10357

Answers (5)

Crustamet
Crustamet

Reputation: 104

private function select($modules, $level = 0)
{
    $return_html = '';
    $level_html = '';
    $new_level = 0;

    foreach($modules as $module)
    {
        $repeat = str_repeat('     ', $level);

        if(!empty($module['children']))
        {
            $return_html .= '<option>' . $repeat . ' ' . $module['title'] . '</option>';

            $new_level = $level + 1;

            $return_html .= $this->select($module['children'], $new_level);
        }
        else
        {
            $return_html .= '<option>' . $repeat . ' ' . $module['title'] . '</option>';
        }
    }
    return $return_html;
}

Upvotes: 0

Adam Arold
Adam Arold

Reputation: 30538

In Java you can inspect the call stack. I think you can do the same in PHP:

debug-backtrace may be the one you are looking for.

Since PHP does not optimize recursion with tail calls this should tell you the depth of the recursion.

Upvotes: 0

litechip
litechip

Reputation: 336

function doSomething($things) {
    static $level = 0;
    if (is_array($things)) {
        foreach ($things as $thing) {
            $level++;
            doSomething($thing);
        }
    }
    else {
        // This is what I want:
        echo $level
    }
}

Upvotes: -1

Fleshgrinder
Fleshgrinder

Reputation: 16273

You need to count it yourself. The only alternative would be something like Xdebug which profiles your complete software. But this is highly inefficient.

<?php
    function my_recursive_fn($param) {
        static $counter = 0;
        if (is_array($param)) {
            ++$counter;
            foreach ($param as $k => $v) {

            }
        }
        else {
            echo $counter;
            --$counter;

            // If we're returning (only PHP 5.5+)
            try {
                return $counter;
            }
            finally {
                --$counter;
            }
        }
    }
?>

This allows you to count without a second public parameter.

Upvotes: 1

Michael Morris
Michael Morris

Reputation: 549

If you are just looking to avoid hitting PHP's 100 level recursion limit then

count(debug_backtrace()); 

should be sufficient. Otherwise you've no choice to pass a depth argument, though the precrement operator makes it somewhat cleaner as seen in the example below.

function recursable ( $depth = 0 ) {
  if ($depth > 3) {
    debug_print_backtrace();
    return true;
  } else {
    return recursable( ++$depth );
  }
}

Upvotes: 10

Related Questions