PHP 递归中断

标签 php recursion

我不太习惯递归函数,也不明白如何正确退出函数。

我尝试从数据库中的父项(使用 Laravel)识别子项(孙子等)列表。

public function getChildren($parentId, $allChildrenArray = Array()){
    $children = DB::table('myTable')->where('parent',$parentId)->get();
    if (sizeof($children)>0){
        foreach ($children as $child) {
            array_push($allChildrenArray,array($child->slug, $child->id));
            MyController::getChildren($child->id, $allChildrenArray);
        }   
    }else{
        // var_dump($allChildrenArray); displays a proper array
        return $allChildrenArray;
    }
}

我对此有两个问题。

  1. 据我了解,我的脚本一旦遇到死胡同,它就会停止传播。但如果还有其他路径可供探索怎么办?
  2. 如果我显示 var_dump($allChildrenArray),则会显示一个数组,看起来没问题。 但是,如果我尝试从其他函数显示它,我会得到 null...

    public function doStuff($itemId){
        $allChildrenArray = MyController::getChildren($itemId);
        var_dump($allChildrenArray); // displays null
    }
    

最佳答案

首先,您应该将助手放在 Controller 之外:)

更重要的是:要理解递归,它有助于逐步进行处理,当您到达递归时,假设我们正在做它应该做的事情,然后稍后再回到那里。

让我们这样开始:

    /**
     * Returns the children for a given parent
     * @param int $parentId
     * @return array
     */
    public function getChildren($parentId){
      $allChildrenArray = array();
  $children = DB::table('myTable')->where('parent',$parentId)->get();
      foreach ($children as $child) {
        array_push($allChildrenArray, array($child->slug, $child->id));
        // Here should be the recursion later
      }   
      // var_dump($allChildrenArray); displays a proper array
      return $allChildrenArray;
    }

现在,如果您查看此函数,您会发现它适用于第一级。很容易看出,在遍历给定父级的子级时,如果您想添加递归,则需要获取这些后代。

    /**
     * Returns the children recursively for a given parent
     * @param int $parentId
     * @return array
     */
    public function getChildren($parentId){
      $allChildrenArray = array();
      $children = DB::table('myTable')->where('parent',$parentId)->get();
      foreach ($children as $child) {
        array_push($allChildrenArray, array($child->slug, $child->id));
        // get descendants of child
        $furtherDescendants = $this->getChildren($child->id);
        // add them to current list
        foreach ($furtherDescendants as $desc) {
          $allChildrenArray[] = $desc; // or use arraypush or merge or whatever
        }
      }   
      // var_dump($allChildrenArray); displays a proper array
      return $allChildrenArray;
    }

现在发生的情况是,当您到达第一个子级时,将开始新的 getChildren 函数运行,将该子级的 id 作为父级 id。如果它没有 child ,那么它将返回一个空数组,否则它将添加该 child 的信息,然后为孙子的 id 作为父 id 开始新的运行,并且...

如果传递数组,您可能可以节省一些内存,但在这种情况下,您需要将其作为引用。此外,当您首先调用此方法时,您需要传递一个变量作为将填充的输入。

    /**
     * Returns the children recursively for a given parent
     * @param int $parentId
     * @param &array $children
     */
    public function getChildren($parentId, &$allChildrenArray) {
      $children = DB::table('myTable')->where('parent',$parentId)->get();
      foreach ($children as $child) {
        array_push($allChildrenArray, array($child->slug, $child->id));
        // get descendants of child
        $this->getChildren($child->id, $allChildrenArray);
      }   
      // var_dump($allChildrenArray); displays a proper array
      return; // nothing to return, children info added to variable passed by reference
    }

    ...

       $kids=array();
       $this->getChildren($parentId, $kids);
       var_dump($kids)

只要确保不要混淆这两种不同的解决方案即可。

退出条件是给定父级没有子级时的情况。在这种情况下,foreach 将不会启动,因此不会进行进一步的递归调用。然而,这仅意味着退出该分支。

关于PHP 递归中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24480499/

相关文章:

python - 使用递归 Python 函数的嵌套 <ul><li> 导航菜单

php - MySQL - 如果输入为空则返回所有值

php/mysql 可能返回不在数据库中的数据吗?

php - AWS php5.4无法连接RDS

php - 使用 URL 路由器会导致 header 授权检索问题

java - 递归字符串解析器

java - StackOverflow 上的递归函数

php - 如何将 oAuth 与 Guzzle 5(或者更好的是,与 Guzzle 6)一起使用

perl - 找到特定文件后,如何摆脱递归查找功能?

python - 递归错误 : maximum recursion depth exceeded while getting the str of an object