【问题标题】:Problem to generate nested ul lists using PHP使用 PHP 生成嵌套 ul 列表的问题
【发布时间】:2023-03-19 03:12:01
【问题描述】:

我正在开发一个前端 Web 应用程序,其中嵌套的无序列表将用于 jQuery 插件 mcdropdown。

这是来自 PHP 的数据结构:嵌套数组:

Array
(
    [0] => Array
        (
            [fullpath] => ../foil/alphanumeric/
            [depth] => 0
        )

    [1] => Array
        (
            [fullpath] => ../foil/alphanumeric/letters/
            [depth] => 1
        )

    [2] => Array
        (
            [fullpath] => ../foil/alphanumeric/numbers/
            [depth] => 1
        )

    [3] => Array
        (
            [fullpath] => ../foil/alphanumeric/numbers/symbols/
            [depth] => 2
        )
)

基本上,我从this question on SO那里得到了很好的答案,稍微修改了一下:

global $fullpaths; // $fullpaths contains the above data structure in print_r
$result = '';
$currentDepth = -1;

while(!empty($fullpaths))
{
    $currentNode = array_shift($fullpaths);

    if($currentNode['depth'] > $currentDepth)
    {
        $result .='<ul>';
    }

    if($currentNode['depth'] < $currentDepth)
    {
        $result .=str_repeat('</ul>', $currentDepth - $currentNode['depth']);
    }

    $result .= '<li>'. $currentNode['fullpath'] .'</li>';

    $currentDepth = $currentNode['depth'];

    if(empty($fullpaths))
    {
        $result .= str_repeat('</ul>', 1 + $currentDepth);
    }
}

print $result;

并得到以下输出:

<ul>
    <li>../foil/alphanumeric/</li>
    <ul>
        <li>../foil/alphanumeric/letters/</li>
        <li>../foil/alphanumeric/numbers/</li>
        <ul>
            <li>../foil/alphanumeric/numbers/symbols/</li>
        </ul>
    </ul>
</ul>

mcdropdown jQuery 插件不能接受,它需要这样的东西:

<li rel="1">
'Alphanumeric'
    <ul>
        <li rel="2">'Letters'</li>
        <li rel="3">'Numbers'
            <ul>
                <li rel="4">'Symbols'</li>
            </ul>
        </li>
    </ul>
</li>

坦率地说,我不太明白该问题的答案是如何工作的,我一直在尝试修改该解决方案以应对我的情况,但仍然失败。

任何帮助和建议都提前得到充分利用。

【问题讨论】:

    标签: php jquery html data-structures


    【解决方案1】:

    如果你已经有了正确的深度值,那么你就不需要递归了。我有一个类似的函数用于

      -
    • -generation:
      function ulli($newlevel, &$level, $UL="ul", $once=1) {
      
        if ($level == $newlevel) {
           echo "</li>\n";
        }
      
        while ($level<$newlevel) {
           $level++;
           echo "\n  <$UL>\n";
        }
      
        while ($level>$newlevel) {
           if ($once-->0) { echo "</li>\n"; } 
           $level--;
           echo "  </$UL>"
           . ($level>0 ? "</li>" : "") . "\n";  // skip for final </ul> (level=0)
        }
      }
      

      它需要一个当前的 $level 变量作为参考 (=$currentDepth)。然后你将它作为 $newlevel 传递给你的深度。然而,它需要第一个深度为 1。

      基本用法如下:

      $currentDepth=0;
      foreach ($array as $_) {
         ulli($_["depth"]+1, $currentDepth);
         echo "<li>$_[path]";
      }
      ulli(0, $currentDepth);
      

      嗯,古怪。但它对我有用。

    【讨论】:

    • 它也适用于我:) 我会做一些修改,我相信 mcdropdown jQuery 插件可以很好地处理输出。非常感谢!
    【解决方案2】:

    这段代码(缩进分开)会产生你想要的结果吗?

    $d = array(
      0 => array(
        'fullpath' => '../foil/alphanumeric/',
        'depth' => 0
        ),
    
      1 => array(
        'fullpath' => '../foil/alphanumeric/letters/',
        'depth' => 1
        ),
    
      2 => array(
        'fullpath' => '../foil/alphanumeric/numbers/',
        'depth' => 1
        ),
    
      3 => array(
        'fullpath' => '../foil/alphanumeric/numbers/symbols/',
        'depth' => 2
        )
      );
    
    echo "<ul>\n";
    $cdepth = 0; $rel = 1; $first = true; $veryfirst = true;
    foreach($d as $e)
    {
      $mpath = "'" . ucfirst(basename($e['fullpath'])) ."'";
      if ( $e['depth'] == $cdepth ) {
        if ( $first && !$veryfirst) { echo "</li>\n";}
        echo "<li rel=\"$rel\">", $mpath;
        $rel++; $first = false; $veryfirst = false;
      } else {
        $depthdiff = $e['depth'] - $cdepth;
        if ( $depthdiff < 0 ) {
          for($i = 0; $i < -$depthdiff; $i++) {
        echo "</ul>\n</li>\n";
          }
        } else {
          for($i = 0; $i < $depthdiff; $i++) {
        echo "\n<ul>\n";
        $first = true;
            // indeed buggy if $depthdiff > 1...
          }
        }
        echo "<li rel=\"$rel\">", $mpath, "\n";
        $rel++; $first = true;
      }
      $cdepth = $e['depth'];
    }
    for($i = 0; $i < $cdepth; $i++) {
      echo "</ul>\n</li>\n";
    }
    echo "</ul>\n";
    

    编辑过的代码:仍然不完美,但您可以处理它...:D

    【讨论】:

    • 我已经做到了,所以每次深度变化都会产生另一个 li;相反,如果来自更改级别的新 ul 必须是 prev li 的一部分,则您必须修改一些代码。我没有在所有情况下都对其进行测试(只是快速编码)
    • hm,我有点草率,现在我已经看到了预期的结果应该是什么;正在编写新代码...
    • 感谢代码和您的更新。我刚下班回家,现在我也在做这个:)
    • 希望你能提取一些有用的东西;即使它或多或少地再现了您给出的工作输出,代码也确实不完美;我刚才注意到我已经添加了 $veryfirst 但它应该是多余的......
    • 是的,我现在可以看到逻辑了。但是实际上填充数组的是业务人员,所以我明天会检查它,看看它与实际数据的关系如何(秘密:他们甚至可能还没有为我的代码做好准备:()
    猜你喜欢
    • 2010-09-28
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多