我的功能看起来像那样。它工作但很多工作(递归调用自己并执行大量的数据库查询)。必须有另一种方法来做同样的事情,但使用数组(有一个查询)。我无法弄清楚如何修改此函数以使其与数组一起使用。
function genMenu($parent, $level, $menu, $utype) {
global $db;
$stmt=$db->prepare("select id, name FROM navigation WHERE parent = ? AND menu=? AND user_type=?") or die($db->error);
$stmt->bind_param("iii", $parent, $menu, $utype) or die($stmt->error);
$stmt->execute() or die($stmt->error);
$stmt->store_result();
/* bind variables to prepared statement */
$stmt->bind_result($id, $name) or die($stmt->error);
if ($level > 0 && $stmt->num_rows > 0) {
echo "\n<ul>\n";
}
while ($stmt->fetch()) {
echo "<li>";
echo '<a href="?page=' . $id . '">' . $name . '</a>';
//display this level's children
genMenu($id, $level+1, $menu, $utype);
echo "</li>\n\n";
}
if ($level > 0 && $stmt->num_rows > 0) {
echo "</ul>\n";
}
$stmt->close();
}
答案 0 :(得分:2)
你可以很容易地构建一个基于树的数组,所以它是一个单一的查询,然后是一堆PHP逻辑来进行数组构建:
$tree = array();
$sql = "SELECT id, parent, name FROM menu WHERE parent ... etc.... ";
$results = mysql_query($sql) or die(mysql_error());
while(list($id, $parent, $name) = mysql_fetch_assoc($results)) {
$tree[$id] = array('name' => $name, 'children' => array(), 'parent' => $parent);
if (!array_key_exists($tree[$parent]['children'][$id])) {
$tree[$parent]['children'][$id] = $id;
}
}
为此,我假设您的树有一个顶级'0'节点。如果没有,那么你将不得不稍微调整一下。
这会给你一个双链接的树结构。树中的每个节点都有['children']
子阵列中的子节点列表,树中的每个节点也通过['parent']
属性指向其父节点。
给定某个起始节点,您可以像这样遍历树:
$cur_node = 57; // random number
$path = array();
do {
$parent = $tree[$cur_node]['parent'];
$path[] = $parent;
$cur_node = $parent;
} while ($parent != 0);
答案 1 :(得分:1)
我认为您可以解决的首要问题是删除WHERE parent =?子句然后处理生成的查询结果,这将使您在管理结果方面工作更多,但肯定会保护您的IO操作。
使用Marc B Solution的部分
$tree = array();
$sql = "select id, parent, name FROM navigation AND menu=? AND user_type=?";
$results = mysql_query($sql) or die(mysql_error());
while(list($id, $parent, $name) = mysql_fetch_assoc($results)) {
$tree[$id] = array('name' => $name, 'children' => array(), 'parent' => $parent);
if (!array_key_exists($tree[$parent]['children'][$id])) {
$tree[$parent]['children'][$id] = $id;
}
}
print_r($tree);
更换?使用实际值,并给出一个运行,你的输出是什么?
答案 2 :(得分:1)
也许不是你想要的,但在trees方面它很棒。 你必须重建你的表并有一些代码输出html,但你只有一个查询。从长远来看,这可能是值得的。
ie。如果你有这个菜单
# Menu hierarchy: - Home - Product |- Tv |- Radio - About us
在db。中看起来像这样。
+----+----------+-----------+-----+-----+ | id | menu | parent_id | lft | rgt | +----+----------+-----------+-----+-----+ | 1 | Home | null | 1 | 2 | +----+----------+-----------+-----+-----+ | 2 | Product | null | 3 | 8 | +----+----------+-----------+-----+-----+ | 3 | Tv | 2 | 4 | 5 | +----+----------+-----------+-----+-----+ | 4 | Radio | 2 | 6 | 7 | +----+----------+-----------+-----+-----+ | 5 | About us | null | 9 | 10 | +----+----------+-----------+-----+-----+
可以使用类似的查询来获取数据
$select = "SELECT * FROM table_name WHERE lft BETWEEN 3 AND 8;"
输出特定菜单:
- Product |- Tv |- Radio
我知道它不是您正在寻找的答案,但仅供参考,还有其他方法可以使用分层树数据。
祝你好运。答案 3 :(得分:0)
我过去用丑陋的方式写过,但用简单的SELECT:
我存储在text / varchar字段中,如下所示:
/001
/001/001
/001/002
/002
/002/001
/002/001/001
忽略希伯来语并查看window.aMessages数组,看看它是如何工作的: http://www.inn.co.il/Forum/Forum.aspx/t394009#4715854