8

如何获取 PHP 函数中的当前递归级别?

我的意思是,有没有像下面这样的“神奇”(或最终正常)功能?

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

我知道我可以使用另一个函数参数($level在这个例子中):

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

但我想知道是否有内置函数(或技巧)可以做到这一点。也许有一些东西debug_backtrace(),但它似乎不是一个简单或快速的解决方案。

我没有找到这个信息。也许它根本不存在......

4

5 回答 5

9

如果您只是想避免达到 PHP 的 100 级递归限制,那么

count(debug_backtrace()); 

应该足够了。否则,您无法选择传递深度参数,尽管 precrement 运算符使其更清晰,如下例所示。

function recursable ( $depth = 0 ) {
  if ($depth > 3) {
    debug_print_backtrace();
    return true;
  } else {
    return recursable( ++$depth );
  }
}
于 2015-01-28T13:51:50.690 回答
1

你需要自己数一数。唯一的选择是像Xdebug这样分析你的完整软件。但这是非常低效的。

<?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;
            }
        }
    }
?>

这允许您在没有第二个公共参数的情况下进行计数。

于 2013-11-12T09:59:28.830 回答
0

在 Java 中,您可以检查调用堆栈。我认为你可以在 PHP 中做同样的事情:

debug-backtrace可能是您正在寻找的那个。

由于 PHP 不使用尾调用优化递归,这应该告诉您递归的深度。

于 2013-11-12T12:26:30.110 回答
0
private function select($modules, $level = 0)
{
    $return_html = '';
    $level_html = '';
    $new_level = 0;

    foreach($modules as $module)
    {
        $repeat = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;', $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;
}
于 2020-09-15T12:17:24.470 回答
-1
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
    }
}
于 2013-11-12T10:02:20.377 回答