【问题标题】:Recursive Nested Navigation with PHP使用 PHP 的递归嵌套导航
【发布时间】:2017-08-29 13:50:29
【问题描述】:

我知道这个问题很多,但我无法让它正常工作。

我有什么 一个获取页面 id (fk_page) 的 PHP 函数。 在此函数内部,调用相同的函数来查找子页面。

我的数据库如下所示:

PHP 代码如下所示:

private function createNav($parent = 0, $sub = false) {
        // *!* Create Nav
        $getNavPage = $this->model->loadNav($parent); // array of menu items (fk_page) that have $parent as parent.

        $NavPage = 0;
        foreach ($getNavPage as $getPage) {

            $NavPage = intval($getPage["fk_page"]);

            $subnav = $this->createNav($NavPage, true); // get childs (recursive loop) and save fk_page in $subnav

            if($sub === false) $this->navArr[$parent][] = $NavPage;
            else $this->navArr[$parent][][] = $NavPage;
        }

        return $NavPage;
}

模型执行以下操作

public function loadNav($parent) {
    $stmt = $this->pdo->prepare("SELECT fk_page FROM nav WHERE fk_parentpage = " . $parent . ";");
            $stmt->execute();
    return $stmt->fetchAll();
}

现在结果是一个看起来像这样的数组

array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
  [2]=>
  array(1) {
    [0]=>
    array(1) {
      [0]=>
      int(4)
    }
  }
  [3]=>
  array(2) {
    [0]=>
    array(1) {
      [0]=>
      int(5)
    }
    [1]=>
    array(1) {
      [0]=>
      int(6)
    }
  }
}

我想要的结果:

array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
      array(1) {
        [0]=>
        array(1) {
          [0]=>
          int(4)
        }
    }
    [3]=>
      array(2) {
        [0]=>
        array(1) {
          [0]=>
          int(5)
        }
        [1]=>
        array(1) {
          [0]=>
          int(6)
        }
      }
  }
}

我相信 createNav() 必须在写入数组元素之前运行(甚至在数组 $this->NavArr 中),但我并没有真正成功。

【问题讨论】:

  • 那么,在您的数据库中,您有 ID、Name、Parent ID 吗?
  • @BrianGottier 用数据库更新了问题。 fk = 外键
  • 我有自己的方式来做你正在做的事情,但它们不太相似,而且代码太多,无法评论。即便如此,即使您没有确切的 ID、名称和父 ID,您仍然有父子层次结构的概念。也许这可以帮助:gist.github.com/anonymous/f4e5f1b1dd4878e394ec0ef2322e4cc4

标签: php recursion navigation parent


【解决方案1】:

这是一个使用本地数据但模仿您正在尝试做的事情的示例:

$data_array = array(
    0 => array(1, 2, 3)
    , 2 => array(4)
    , 3 => array(5, 6)
);

function get_kids($id = 0) {
    global $data_array;
    if(isset($data_array[$id])) {
        return $data_array[$id];
    }
    else {
        return array();
    }
}

function create_navigation($parent_id = 0) {

    // Check for children
    $children_array = get_kids($parent_id);

    // No children - just return the parent
    if (empty($children_array)) {
        return $parent_id;
    }

    // Children!
    foreach ($children_array as $key => $child_id) {
        $children_array[$key] = create_navigation($child_id);
    }

    return array($parent_id => $children_array);
}

echo '<pre>';
    $nav = create_navigation(0);
    var_dump($nav);
    print_r($nav);
echo '</pre>';

使用$data_array 代替您的数据库。

get_kids 函数是您的 loadNav 方法。

create_navigation 函数是您的 createNav 方法。

这会产生一个var_dump

array(1) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    array(1) {
      [2]=>
      array(1) {
        [0]=>
        int(4)
      }
    }
    [2]=>
    array(1) {
      [3]=>
      array(2) {
        [0]=>
        int(5)
        [1]=>
        int(6)
      }
    }
  }
}

还有一个print_r

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => Array
                (
                    [2] => Array
                        (
                            [0] => 4
                        )

                )

            [2] => Array
                (
                    [3] => Array
                        (
                            [0] => 5
                            [1] => 6
                        )

                )

        )

)

您的原始代码的问题是您将 ID 分配给类变量 $this-&gt;navArr,而不是使用递归来返回子元素 ($subnav)。

【讨论】:

  • 谢谢,我成功了,我想我开始明白为什么...我尝试记录每一步,它究竟做了什么,因为这对我来说很难想象和解释。这就是为什么我会犯愚蠢的逻辑错误......
猜你喜欢
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
  • 1970-01-01
  • 2014-10-01
  • 2018-05-28
  • 2017-02-02
  • 2019-07-07
相关资源
最近更新 更多