通过 PHP 使用 mysql 进行递归树遍历
Posted
技术标签:
【中文标题】通过 PHP 使用 mysql 进行递归树遍历【英文标题】:Recursive tree traversal with mysql through PHP 【发布时间】:2012-06-15 04:16:38 【问题描述】:我正在为一位客户创建一份问卷,该问卷要求按 3 层级别组织问题。我已经成功创建了 U.I.但是,在过去的 3 个小时里,我一直在尝试从数据库中提取数据,以使所有内容都加载到正确的位置。数据库是由客户端组织的,所以我无法控制它:
id description parentId
1 Level 1 0
2 Level 2 0
3 Level 1a 1
4 Level 1b 1
5 Level 1a1 3
我在网站上发现了一个与我类似的问题,但是当我尝试它的解决方案时,我得到了以下无限重复:
代码:
function makeList($par_id = 0)
//your sql code here
$result = mysql_query("SELECT * FROM pB_test WHERE parentId = $par_id");
$pages = mysql_fetch_array( $result );
if (count($pages))
echo '<ul>';
foreach ($pages as $page)
echo '<li>', $page['description'];
makeList($page['parentId']);
echo '</li>';
echo '</ul>';
makeList();
输出:
1
3
5
5
l
l
3
5
5
l
l
3
5
5
l
l
3
5
5
l
l
有谁知道如何解决这个问题以及问题到底是什么?干杯
【问题讨论】:
MySQL 不支持递归JOIN
s,这是您真正需要的,但是如果您知道您只有三个级别并且永远只有三个级别,您可以将表连接到自己三倍
【参考方案1】:
每次都调用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);
表格的常见示例
id name parent_id
【讨论】:
您可以将global $arrs;
(而不是将其作为参数传递)放在函数内部。它不再是黑匣子,但您将使用更少的内存。也使用 mysqli 代替 mysql。反正我喜欢。
这将始终获取完整的表,可能使用 TB 的 RAM - 不可能获取子树,
@EugenRieck,只需将WHERE parent_id=$parent_id
子句添加到您的查询中,并将第二个参数添加到build_tree($arrs, $parent_id)
调用中。很明显它不适合大数据,但你会按照 OP 的要求将 TB 的结果包装在 <ul><li>
中吗?
没错。我永远不会将 TB 包装到 <ul><li>
,但我会将 TB 放入数据库。这个损坏的代码将始终获取所有行,因此what if you have over 100 rows? or 200+
的答案很简单:绝对不是这个,因为它会在任何大树上严重损坏。
谢谢@vladkras,到目前为止,这是我找到的最佳解决方案【参考方案2】:
递归执行:
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);
【讨论】:
有效!太感谢了!你今天赢得了互联网,伙计! 好的,然后我将如何将数据组织到 div 中,所以说 level1 是所有子级的容器,其中还有另一个 div 容器。那么 level2 是列表中的下一个容器吗? 你得问一个单独的问题:我是 php/SQL 人,不是 html 人,很抱歉 它应该仍然适用吧?如何拆分它以便每个级别都可以嵌套它自己的 html 标记?如果你做不到也没关系。不过感谢您的帮助! 基本上从我的代码开始:我回显<ul>
你应该回显你的起始HTML,</ul>
成为你的结束HTML。 <li> ... </li>
行是您的问题。所以我怀疑它应该像开始 <div class="..">
,结束 </div>
和中间的格式化问题。以上是关于通过 PHP 使用 mysql 进行递归树遍历的主要内容,如果未能解决你的问题,请参考以下文章