通过PHP实现mysql递归树遍历
我正在为一位客户创建一份调查问卷,要求将问题分为3个层次。我已经成功地创建了U.I。然而,在过去的3个小时里,我一直在尝试从数据库中提取数据,以确保所有数据都加载到正确的位置。数据库是由客户组织的,因此我无法控制它:通过PHP实现mysql递归树遍历,php,mysql,loops,recursion,traversal,Php,Mysql,Loops,Recursion,Traversal,我正在为一位客户创建一份调查问卷,要求将问题分为3个层次。我已经成功地创建了U.I。然而,在过去的3个小时里,我一直在尝试从数据库中提取数据,以确保所有数据都加载到正确的位置。数据库是由客户组织的,因此我无法控制它: id description parentId 1 Level 1 0 2 Level 2 0 3 Level 1a 1 4 Lev
id description parentId
1 Level 1 0
2 Level 2 0
3 Level 1a 1
4 Level 1b 1
5 Level 1a1 3
我在网站上发现了一个与我类似的问题,但当我尝试它的解决方案时,我得到了以下不确定的重复:
代码:
有人知道如何解决这个问题吗?问题到底是什么?干杯反复这样做:
function printChildQuestions($parentid) {
$sql="SELECT * FROM pB_test WHERE parentID=$parentid";
$result=mysql_query($sql);
$i=0;
while (true) {
$row=mysql_fetch_array($result);
if (!$row) break;
if ($i==0) echo "<ul>";
$i=1;
echo '<li>'.$row['id'].' '.$row['description'].' '.$row['parentId'].'</li>';
printChildQuestions($row['id']);
}
if ($i>0) echo '</ul>';
}
printChildQuestions(0);
函数printChildQuestions($parentid){
$sql=“从pB\U测试中选择*,其中parentID=$parentID”;
$result=mysql\u查询($sql);
$i=0;
while(true){
$row=mysql\u fetch\u数组($result);
如果(!$行)中断;
如果($i==0)回波“- ”;
$i=1;
回显“
- ”。$row['id'..”.$row['description'..”.$row['parentId'.. ”; 打印儿童问题($row['id']); } 如果($i>0)回显“
每次调用mysql服务器并获取结果都不好 如果你有超过100行呢?或者200+ 使用此选项仅查询一次:
$result = mysql_query("SELECT * FROM test");
$arrs = array();
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$arrs[] = $row;
}
function build_tree($arrs, $parent_id=0, $level=0) {
foreach ($arrs as $arr) {
if ($arr['parent_id'] == $parent_id) {
echo str_repeat("-", $level)." ".$arr['name']."<br />";
build_tree($arrs, $arr['id'], $level+1);
}
}
}
build_tree($arrs);
MySQL不支持递归的
JOIN
s,这正是您真正需要的,但是如果您知道您只有三个级别,并且将永远只有三个级别,那么您只需将表自身连接三次即可!非常感谢你!你今天赢了,伙计!好的,那么我如何将数据组织到div中,比如说level1是它所有子级的一个容器,其中有另一个div容器。那么level2是列表中的下一个容器吗?你必须问一个单独的问题:我是一个PHP/SQL的人,不是HTML的人,很抱歉,它应该仍然适用,对吗?如何将其拆分,以便每个级别都可以嵌套自己的html标记?如果你做不到,那没关系。谢谢你的帮助!基本上从我的代码开始:在我回显的地方,你应该回显你的起始HTML,
成为你的结束HTML。行
是您的问题。所以我怀疑它应该是像开始代码> >代码>,结束<代码> <代码>和中间的格式化问题。你可以放<代码>全局$ARS;<代码>(而不是作为参数传递)在函数内部。它将不再是一个黑匣子,但您将使用更少的内存。也可以使用mysqli而不是mysql。无论如何,我喜欢它。这将始终获取完整的表,可能使用TB的RAM-不可能获取子树,@EugenRieck,只需将WHERE parent\u id=$parent\u id
子句添加到查询中,并将第二个参数添加到build\u tree($arrs,$parent\u id)
调用中。很明显,它不适合大数据,但您会按照OP的要求将TB级的结果封装在中吗?没错。我永远不会将TB压缩到,但我会将TB压缩到DB中。这段中断的代码将始终获取所有行,因此的答案是如果您有100多行呢?或者200+
很简单:绝对不是这样,因为它会在任何一棵相当大的树上严重损坏。谢谢@vladkras,到目前为止,这是我找到的最好的解决方案
function printChildQuestions($parentid) {
$sql="SELECT * FROM pB_test WHERE parentID=$parentid";
$result=mysql_query($sql);
$i=0;
while (true) {
$row=mysql_fetch_array($result);
if (!$row) break;
if ($i==0) echo "<ul>";
$i=1;
echo '<li>'.$row['id'].' '.$row['description'].' '.$row['parentId'].'</li>';
printChildQuestions($row['id']);
}
if ($i>0) echo '</ul>';
}
printChildQuestions(0);
$result = mysql_query("SELECT * FROM test");
$arrs = array();
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$arrs[] = $row;
}
function build_tree($arrs, $parent_id=0, $level=0) {
foreach ($arrs as $arr) {
if ($arr['parent_id'] == $parent_id) {
echo str_repeat("-", $level)." ".$arr['name']."<br />";
build_tree($arrs, $arr['id'], $level+1);
}
}
}
build_tree($arrs);
id name parent_id