正确递归

时间:2009-05-07 19:18:11

标签: php recursion

我有几个导航相关的功能,我希望没有深度限制。这些会生成CSS菜单,痕迹痕迹等。

我很难过如何使函数遵循每条路径深度或根目录而没有明确的循环。

以下是我想要页面最顶层父项的典型示例。最顶层的parent字段的值为零。

这是显式循环版本:

function topPg() {
    $p = $this->retrieve("id = '$this->parent'");
    if ($p->parent != 0) {
        $gp = $this->retrieve("id = '$p->parent'");
        if ($gp->parent != 0) {
            $ggp = $this->retrieve("id = '$gp->parent'");
            if ($ggp->parent != 0) {
                $gggp = $this->retrieve("id = '$ggp->parent'");
                // ad naseum
            } else {
                return $ggp;
            }
        } else {
            return $gp;
        }
    } else {
        return $p;
    }
} // func

任何人都有建议或类似的代码或tute链接来帮助指明方向?

3 个答案:

答案 0 :(得分:8)

它很容易表现为while循环:

$node = $this;
while ($node->parent != 0) {
  $node = $this->retrieve("id = '$node->parent'");
}

$node现在包含最顶层的元素。

答案 1 :(得分:1)

Welbog's answer是最好的,但为了完整性,我将添加另一个递归解决方案:

function topPg() {
   function foo($p) {
     $gp = $this->retrieve("id = '$p->parent'");
     return ($gp->parent == 0) ? $p : foo($gp);
   }  

   return foo($this);
}

答案 2 :(得分:0)

我还没有测试过,但它应该有效..:

function recurse( $pg )
{
    $parent_pg = $pg->retrieve( 'id = ' . $this->parent );

    if( $parent_pg->parent != 0 )
    {
        recurse( $parent_pg );
    }
    else
    {
        return $pg;
    }

}