【问题标题】:PHP category tree recursionPHP类别树递归
【发布时间】:2012-03-18 11:24:50
【问题描述】:

我需要通过一个数组递归来构建一个类别表。只要深度越深,它就可以正常工作,但一旦深度减小,HTML 输出就会错过表格的开头。

构建数组的PHP代码:

       if($query->rowCount() > 0) {
        while($result = $query->fetch(PDO::FETCH_OBJ)) {
            $tree[] = $result;
        }
        $childs = array();

        foreach($tree as $item) {
            $childs[$item->parent_id][] = $item;
        }


        foreach($tree as $item) {
            if (isset($childs[$item->id])) {
               $item->childs = $childs[$item->id];
            }
        }

        $tree = $childs[0];
    }
    else {
        // no category blabla
    }

这里是建表的函数。它无法正常工作。

    function draw($tree) {
    echo "<table border='1' width='300'>";
    echo "<tr>";
    echo "<td>Name</td><td>Depth</td><td>Parent</td>";
    echo "</tr>";
    foreach($tree as $key => $value) {
        echo "<tr>";
        echo "<td>".$value->name."</td>";
        echo "<td>".$value->depth."</td>";
        echo "<td>".$value->parent_id."</td>";
        echo "</tr>";
        if(isset($value->childs)) {
            draw($value->childs);
        }
    }
    echo "</table>";

}

根据要求 HTML 输出 sn-p:

<table border='1' width='300'>
    <tr>
        <td>Name</td>
        <td>Depth</td>
        <td>Parent</td>
    </tr>
    <tr>
        <td>Bad</td>
        <td>5</td>
        <td>5</td>
    </tr>
    <tr>
        <td>Good</td>
        <td>5</td>
        <td>5</td>
    </tr>
</table>
    <!--- BREAK HAPPENS HERE----->
    <tr>
        <td>Both?</td>
        <td>4</td>
        <td>3</td>
    </tr>
    <table border='1' width='300'>
        <tr>
            <td>Name</td>
            <td>Depth</td>
            <td>Parent</td>
        </tr>
        <tr>
            <td>dsadas</td>
            <td>5</td>
            <td>16</td>
        </tr>
    </table>

【问题讨论】:

  • 你介意通过在你的 foreach 和 if 语句周围添加花括号来检查它是否按预期工作,以明确你的意思吗?在 FOREACH 之后有一个 IF 可能是意外或故意的。请用大括号{}澄清?
  • 为什么会有echo "";高于平局($value->childs);?摆脱那个结束表标签
  • @MyStream 数组创建工作作为意图。树数组的 var_dump 与它应该的完全一样,所以这不是问题。 hackartist:我忘了补充一点,每次表格跳转到新的深度时,它都应该重新发布表格标题。这就是为什么有最后一张桌子。编辑:即使在删除它之后,也会发生相同的表中断,所以这也不是问题
  • @Sepix:它仍然很难阅读(并且对于可维护性来说不是好的做法(旁注))-并且“应该是”,但是您在哪里(什么级别)得到了意外的 html 输出?第一个循环没有孩子?
  • html 标签成对出现。在平局中,您有 1 张桌子打开,至少有一张桌子关闭,但可能还有更多桌子关闭。这不会是平衡的。

标签: php html arrays recursion tree


【解决方案1】:
  function draw($tree) {
    if(!$tree) return;
    $nextLevel = array();
    echo "<table border='1' width='300'>";
    echo "<tr>";
    echo "<td>Name</td><td>Depth</td><td>Parent</td>";
    echo "</tr>";
    foreach($tree as $key => $value) {
        echo "<tr>";
        echo "<td>".$value->name."</td>";
        echo "<td>".$value->depth."</td>";
        echo "<td>".$value->parent_id."</td>";
        echo "</tr>";
        if(isset($value->childs) && $value->childs){
           $nextLevel = array_merge($nextLevel, $value->childs);
        }
    }
    echo "</table>";
    draw($nextLeveL);
}

【讨论】:

  • 这个可以正常工作,但打印的表格并不是真正的树。它首先列出所有第 1 层,然后列出所有第 2 层,然后列出所有第 2 层。我有你的结果以及它最终应该是什么样子:linklink 第二个当然应该在没有中断的情况下发生底部:)。
【解决方案2】:

这样做:

    echo "<tr><td colspan='3'>";
    if(isset($value->childs)) {
        draw($value->childs);
    }
    echo "</td></tr>"

改为这样做:

    if(isset($value->childs)) {
        echo "<tr><td colspan='3'>";
        draw($value->childs);
        echo "</td></tr>"
    }

您正在表格主体内创建一个新表格。那是无效的 HTML。你必须把它放在它自己的 TD 中。

【讨论】:

  • 我不是在创造那个。脚本是问题所在。我知道 HTML 代码应该是怎样的,问题是将其传授给递归 PHP 函数。 :)
  • @Sepix:不过,根据 Daan Timmer 所说,尝试添加相同的代码,但将 tr/td colspan=3 放在 if(isset()) {} 块中,它应该包装带有单个 td 的内部输出 - 这应该紧随其后?
  • 实际上几乎可以工作!不敢相信。现在唯一的问题是,当他进入外层时,桌子上方没有标题。图片:link
  • 好的。我最终以不同的方式解决了它,但这绝对给了我理解这个递归东西所需的提示。非常感谢……经过 40 小时的挣扎,我终于可以再次正常入睡了!
  • @Sepix,没问题。我会用 MyStream 所说的来改变我的答案。他确实是对的,我的错!
猜你喜欢
  • 1970-01-01
  • 2014-03-20
  • 2012-07-14
  • 1970-01-01
  • 2016-07-18
  • 1970-01-01
  • 2021-11-24
  • 2015-04-25
  • 1970-01-01
相关资源
最近更新 更多