使用PHP生成嵌套ul列表的问题

时间:2010-06-07 09:21:07

标签: php jquery html data-structures

我正在开发一个前端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>
坦率地说,我不太明白这个问题的答案是如何起作用的,我一直试图修改这个解决方案来应对我的情况,但仍然失败了。

任何帮助和建议都要提前拨款。

2 个答案:

答案 0 :(得分:2)

如果您已经有正确的深度值,那么您不需要递归。我有一个类似的功能,我用于&lt; ul&gt; - &lt; li&gt; - 生成:

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);
好吧,古怪。但它对我有用。

答案 1 :(得分: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