在PHP中使用数组而不是大量的db查询
我的函数看起来是这样的。它可以工作,但需要做大量的工作,递归地调用自身并执行大量的数据库查询。必须有另一种方法来做同样的事情,但是使用带有一个查询的数组。我不知道如何修改此函数以使其与数组一起工作在PHP中使用数组而不是大量的db查询,php,mysql,mysqli,prepared-statement,Php,Mysql,Mysqli,Prepared Statement,我的函数看起来是这样的。它可以工作,但需要做大量的工作,递归地调用自身并执行大量的数据库查询。必须有另一种方法来做同样的事情,但是使用带有一个查询的数组。我不知道如何修改此函数以使其与数组一起工作 function genMenu($parent, $level, $menu, $utype) { global $db; $stmt=$db->prepare("select id, name FROM navigation WHERE parent = ? AND menu
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();
}
我以前写过一种丑陋的方式,但用的是简单的选择: 我存储在text/varchar字段字符串中,如下所示:
/001
/001/001
/001/002
/002
/002/001
/002/001/001
$cur_node = 57; // random number
$path = array();
do {
$parent = $tree[$cur_node]['parent'];
$path[] = $parent;
$cur_node = $parent;
} while ($parent != 0);
忽略希伯来语并在window.aMessages数组中查找,以查看其工作原理:
我认为您可以解决的第一件事是删除WHERE parent=?子句,然后处理结果查询结果,这将使您在管理结果方面做得更多,但肯定会确保IO操作的安全 使用marcb解决方案的一部分
更换?使用实际值,运行一次,您的输出是什么?您可以非常轻松地构建基于树的数组,因此只需一个查询,然后使用一组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']属性指向其父节点
给定某个起始节点,可以如下方式遍历树:
/001
/001/001
/001/002
/002
/002/001
/002/001/001
$cur_node = 57; // random number
$path = array();
do {
$parent = $tree[$cur_node]['parent'];
$path[] = $parent;
$cur_node = $parent;
} while ($parent != 0);
也许这不是你想要的,但当涉及到这个问题时,它是很棒的。 您必须重新构建表并使用一些代码来输出html,但您只有一个查询。从长远来看,这是值得付出努力的 如果你有这个菜单 # Menu hierarchy: - Home - Product |- Tv |- Radio - About us 在数据库中看起来是这样的 +----+----------+-----------+-----+-----+ | 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 我知道这并不完全是你想要的答案,但仅供参考,还有其他方法可以使用层次树数据
祝你好运。我看不出你在代码外观中再次声明$id。我这样声明$stmt->bind_result$id、$name或die$stmt->error;它在prepped语句语法中会是什么样子?基本上与您的相同,除了不使用单独的查询获取每个单独的菜单项,而是在一个单独的查询中获取所有菜单项,然后使用PHP在客户端构建树状结构。那么在获取之后我需要做什么?如果可能的话,请修改我的代码,我不明白为什么我的答案应该是-1?我不知道为什么巨魔会无缘无故地投反对票,但我尊重任何试图帮助我并为我浪费他/她的黄金时间的人+1快速回复。谢谢mate@MarcB解决方案与我的解决方案相同,但他给出了代码示例,基本上您需要做的是使用树数组,它将具有列表的结构。执行MarcB提供的代码后,插入一个echo;这看起来像是正确的结构吗?你能帮我修改代码吗?我不知道我到底需要什么来修改MySQL?获取?作为预备状态的备选方案?