【问题标题】:How do I output an tree-like array into a list with php?如何使用 php 将树状数组输出到列表中?
【发布时间】:2018-01-10 19:28:30
【问题描述】:

我的主要问题是我想使用 PHP 在 HTML 中生成一个无序列表。我从 SQL 查询中获取数据,然后需要使用我自己编写的 PHP 函数将其连接到无序列表中。每个项目都应该是一个li,如果它有一个子项目,它应该打开一个新的ul,子项目为li,它又可以包含子项目等。

我有一个数组,我输出树本身的每个部分。它看起来像这样:

[0] => Array (
    [0] => Application Integration
    [1] => 
    )
[1] => Array (
    [0] => Application Integration
    [1] => Windows
    [2] => 
    )
[2] => Array (
    [0] => Application Integration
    [1] => Windows
    [2] => Leitungen
    )
[3] => Array (
    [0] => Application Integration
    [1] => Windows
    [2] => Leitungen
    [3] => WAN
    )
[4] => Array (
    [0] => Application Integration
    [1] => Windows
    [2] => Leitungen
    [3] => Mail
    )
[5] => Array (
    [0] => Application Integration
    [1] => Windows
    [2] => EDI
    )
[6] => Array (
    [0] => Application Integration
    [1] => Windows
    [2] => EDI
    [3] => Word
    )
[7] => Array (
    [0] => Application Integration
    [1] => Windows
    [2] => EDI
    [3] => LAN
    )
[8] => Array (
    [0] => Application Integration
    [1] => Internet
    [2] => 
    )
[9] => Array (
    [0] => Application Integration
    [1] => Internet
    [2] => Office
    )
[10] => Array (
    [0] => Application Integration
    [1] => Internet
    [2] => Office
    [3] => Powerpoint
    )
[11] => Array (
    [0] => Application Integration
    [1] => Internet
    [2] => Office
    [3] => Excel
    )
[12] => Array (
    [0] => Application Integration
    [1] => Internet
    [2] => Leitungen
    )
[13] => Array (
    [0] => Application Integration
    [1] => Internet
    [2] => Leitungen
    [3] => SQL Developer
    )
[14] => Array (
    [0] => Application Integration
    [1] => Internet
    [2] => Leitungen
    [3] => Pokerstars
    )

我希望输出被一个无序列表包围,其中数组中的每个项目都是一个列表元素,如果它有一个子项,它也应该在一个无序列表中,......它应该看起来像下面的列表:

<ul>
  <li>
    Applicaton Integration
    <ul>
      <li>
        Windows 
        <ul>
          <li>
            EDI
            <ul>
              <li>Word</li>
              <li>LAN</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>
        Internet
        <ul>
          <li></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
...etc

我尝试在 PHP 中编写以下函数,但这并不是我想要的,因为它会提前和/或太晚关闭标签。

function treeOut(array $tree): string{
  $markup = '';
  print_r($tree);
  foreach($tree as $branch) {
    if(!empty($branch[1])){
      $markup.='<ul class="Stufe1">';
      $markup.='<li>';
        if(!empty($branch[2])){
          $markup.='<ul class="Stufe2">';
          $markup.='<li>';
            if(!empty($branch[3])){
              $markup.='<ul class="Stufe3">';
              $markup.='<li>';
              $markup.='<input type="checkbox" name=""/>'.$branch[3];
              $markup.='</li></ul>';
            }else{
              $markup.='<input type="checkbox" name=""/>'.$branch[2];
            }
            $markup.='</ul></li>';
          }else{
          $markup.='<input type="checkbox" name=""/>'.$branch[1];
        }
        $markup.='</li></ul>';
    }else{
      $markup.='<li><input type="checkbox" name=""/>'.$branch[0];
    }
  }
  return $markup;
}

我很抱歉这么多代码,但我会很感激任何帮助。

【问题讨论】:

  • 如果您的数组深度未定义(或至少不总是相同),我建议使用递归,例如当它包含更多项目时,使用子数组调用您的函数,因此您必须编写更少的代码。
  • 你可以尝试在一个子数组中合并第一级的所有不同元素,然后在另一个子数组中合并第二级并继续......然后轻松递归抛出所有级别并创建标记

标签: php arrays algorithm recursion


【解决方案1】:

要解决涉及数据结构嵌套级别的问题,但应该以大致相同的方式处理,递归是您最好的朋友。

如果您不熟悉这种技术,我们的想法是设计一个可以调用自身的函数。

关于您的问题,我们可以考虑这样的事情:

首先,一个函数来修改你的数组,以便它可以被处理。

function nester(array $array, $idx = 0) {
    if (array_key_exists($idx, $array) && !empty($array[$idx])) {
        return array($array[$idx] => nester($array, $idx + 1));
    }
    return array();
}

function treeParser(array $array_tree) {
    $dom_tree = '';
    foreach ($array_tree as $key => $val) {
        if (is_array($val) && count($val)) {
            $dom_tree .= "<li>$key".treeParser($val).'</li>';
        } else {
            $dom_tree .= "<li>$key</li>";
        }
    }
    return ($dom_tree ? "<ul>$dom_tree</ul>" : '');
}

$array_nested = array();

foreach ($array as $value) {
    $array_nested[] = nester($value);
}
$DOM_tree = treeParser(array_merge_recursive(... $array_nested));

在此之前,一个函数会浏览您的每个子数组并将它们转换为嵌套数组,以便我们可以对它们进行递归。在array_merge_recursive 的帮助下,这些数组被合并到您要构建的 DOM 的干净树中。

然后另一个函数将您的数组作为参数并使用 foreach 浏览它。 每次它找到一个数组时,它都会附加一对包含当前数组键的&lt;li&gt; 标签,如果它不为空,最终会在该数组上调用它自己的返回。 当函数的一个实例处理了它的整个子数组时,它返回它的工作——字符串$dom_tree——在&lt;ul&gt;标签之间。 如果该实例是主要实例 - 您自己调用的实例 - 这些 &lt;ul&gt; 标记将是包含整个数据结构的主要无序列表。

理论上,无论您的数组的深度是多少,它都能正常工作,但如果它非常深,请当心 Stack Overflow。

【讨论】:

  • 此解决方案仅适用于嵌套更多的数组。在我的情况下,它只在同一阶段输出每个项目。
  • 我的错,我误解了你的例子。
  • @Gabsii 该死的,您的阵列根本没有针对您的目的进行优化。
  • @Gabsii 已编辑。它现在应该适用于您的格式。
  • 假设 $array 是输入数组,我仍然得到错误的输出。见jsfiddle.net/zx5dbn35/4
猜你喜欢
  • 2017-11-12
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
相关资源
最近更新 更多