2

您好,我有一个用 codeigniter 制作的菜单。但我也希望这个有子菜单

因此,我得到一个数组并使用 foreach 循环遍历它。

        <ul>
            <?php foreach ($menu_item as $menu =>& $key): ?>    
            <li><?php echo anchor($menu, $key, $this->uri->slash_segment(1, 'leading') == $menu ? 'class="active"' : '') ?></li>
            <?php endforeach ?>
        </ul>

现在的问题是,如果它只有一个没有子菜单的菜单,但是当我得到这样的数组时,这很好用

$menu_item = array(
    '/' => 'Home',
    '/about' => 'About',
    '/foo' => 'boo',
    '/contact' => 'contact',
    'test' => array(
               'foo' => 'boo'
              ),

    'test2' => 'foo2'
);

比它不再起作用了。我怎样才能遍历所有内容并将其作为一个好的菜单输出?

4

5 回答 5

2

您可以使用递归来完成这项工作。如果您不熟悉它,您需要花点时间了解它,但它非常适合此类问题。

我没有在 PHP 中运行这段代码,但它会给你一个想法。

基本上发生的情况是主菜单函数检查每个项目以查看它是否是一个数组,然后使用子菜单再次调用该函数。如果需要,这将无限深入。

<?php
  $menu = array(
      '/' => 'Home',
      '/about' => 'About',
      '/foo' => 'boo',
      '/contact' => 'contact',
      'test' => array(
                 'foo' => 'boo'
                ),

      'test2' => 'foo2'
  );
?>

<ul>
  <?php showMenu($menu); ?>
</ul>


<?php
  function showMenu($menu)
  {
    <?php foreach ($menu_item as $menu =>& $key): ?>    
      <li><?php echo anchor($menu, $key, $this->uri->slash_segment(1, 'leading') == $menu ? 'class="active"' : '') ?></li>
      if(is_array($menu_item))
      {
        echo "<ul>";
        showMenu($menu_item);
        echo "</ul>";
      }
    <?php endforeach ?>
  }
?>

希望这可以帮助。

于 2013-08-06T12:42:44.690 回答
1

其他答案的概念是正确的,但它们会生成无效的 DOM 结构,所以我决定修复它。

您可以制作一个helper文件并将drawMenu()函数放入其中。因此,您将能够根据需要尽可能多地调用该函数。

$menu = array(
    '/'        => 'Home',
    '/about'   => 'About',
    '/foo'     => 'boo',
    '/contact' => 'contact',
    'test'     => array(
        'foo' => 'bar',
        'baz' => 'qux'
    ),
    'test2' => 'foo2'
);

function drawMenu($menu)
{
    $CI =& get_instance();

    $output = '';
    foreach ($menu as $key => $value) {
        $output .= "<li>";
        if (is_array($value)) {
            $output .= anchor('#', $key);
            $output .= PHP_EOL."<ul>".PHP_EOL;
            $output .= drawMenu($value);
            $output .= "</ul>".PHP_EOL."</li>".PHP_EOL;
        } else {
            $output .= anchor($key, $value, $CI->uri->slash_segment(1, 'leading') == $key ? 'class="active"' : '');
            $output .= "</li>".PHP_EOL;
        }
    }
    return $output;
}

$html = drawMenu($menu);
echo '<ul>'. $html .'</ul>';

旁注:使用PHP_EOL常量是任意的,它只是使生成的 DOM 更具可读性。


更新:

我改进了drawMenu()功能,现在您可以为子菜单的标题添加 URL 地址:

$menu = array(
    '/'        => 'Home',
    '/about'   => 'About',
    '/foo'     => 'boo',
    '/contact' => 'contact',
    'test'     => array(
        'foo' => 'bar'
    ),
    'This is Test2|/url/to/test2' => array(
        'baz' => 'qux'
    )
);

您可以在分隔符后添加 URL |

function drawMenu($menu)
{
    $CI =& get_instance();

    $output = '';
    foreach ($menu as $key => $value) {
        $output .= "<li>";

        if (is_array($value)) {

            if (strpos($key, '|') !== false) {
                $param = explode('|', $key);
                $output .= anchor($param[1], $param[0]);
            } else {
                $output .= anchor('#', $key);
            }

            $output .= PHP_EOL."<ul>".PHP_EOL;
            $output .= drawMenu($value);
            $output .= "</ul>".PHP_EOL."</li>".PHP_EOL;
        } else {
            $output .= anchor($key, $value, $CI->uri->slash_segment(1, 'leading') == $key ? 'class="active"' : '');
            $output .= "</li>".PHP_EOL;
        }
    }
    return $output;
}
于 2013-08-06T13:46:10.800 回答
1

您可以检查$key是否为数组:is_array

然后你可以使用另一个foreach来循环子菜单。

于 2013-08-06T12:42:42.870 回答
0

尝试这个

<ul>
<?php function buildmenu($menu_item){ ?>
    <?php foreach($menu_item as $item){ ?>
            <li><?php echo anchor($menu, $key, $this->uri->slash_segment(1, 'leading') == $menu ? 'class="active"' : '') ?></li>
            <?php if(is_array($item)){ 
                    buildmenu($item); 
            } ?>
    <?php } ?>
<php} ?>
<?php buildmenu($menu_item) ?>
</ul>
于 2013-08-06T12:44:21.597 回答
0
$menu = "<ul>\n";
foreach ($menu_item as $key => $value){
    if (is_array($value)){
        $menu.= "\t<li>".$key."\n\t\t<ul>\n";
        foreach ($value as $key2 => $value2){
            $menu .= "\t\t\t<li>".$value2."</li>\n";
        }
        $menu.= "\t\t</u>\n\t</li>\n";
    } else {
        $menu .= "\t<li>".$value."</li>\n";
    }
}
$menu .= "</ul>";
echo $menu;

输出:

<ul>
    <li>Home</li>
    <li>About</li>
    <li>boo</li>
    <li>contact</li>
    <li>test
        <ul>
            <li>boo</li>
        </u>
    </li>
    <li>foo2</li>
</ul>
于 2013-08-06T14:07:46.817 回答