使用 PHP 的递归嵌套导航
Recursive Nested Navigation with PHP
我知道很多人问这个问题,但我无法让它正常工作。
我有什么
获取页面 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 内),但我并没有真正成功。
这是一个使用本地数据但模仿您正在尝试执行的操作的示例:
$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 分配给 class 变量 $this->navArr
,而不是对 return 子元素 ($subnav
) 使用递归。
我知道很多人问这个问题,但我无法让它正常工作。
我有什么 获取页面 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 内),但我并没有真正成功。
这是一个使用本地数据但模仿您正在尝试执行的操作的示例:
$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 分配给 class 变量 $this->navArr
,而不是对 return 子元素 ($subnav
) 使用递归。