【问题标题】:iterating over multi dimensional array for a menu迭代菜单的多维数组
【发布时间】:2013-08-07 11:11:52
【问题描述】:

您好,我有一个用 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'
);

比它不再起作用了。如何循环遍历所有内容并将其输出为一个好的菜单?

【问题讨论】:

    标签: php arrays codeigniter multidimensional-array


    【解决方案1】:

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

    我没有在 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 ?>
      }
    ?>
    

    希望这会有所帮助。

    【讨论】:

    • 不幸的是它不起作用我收到一个错误语法错误,文件中的文件意外结束...在第 48 行。函数有问题我发现一些不正确的事情,但即使在之后修复其余部分会导致此错误
    【解决方案2】:

    其他答案的概念是正确的,但是它们会生成无效的 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'
        )
    );
    

    您可以在| 分隔符后添加网址。

    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;
    }
    

    【讨论】:

    • 有了这个我得到致命错误:在 $this->uri 的对象上下文中没有使用 $THIS
    • 这就像一个魅力,只是我没有得到子菜单的主菜单标题,比如“测试”现在必须在将鼠标悬停在它们 bar 和 qux 上时包含这些菜单,因为现在我只是得到只有子菜单的
    • 对不起,我没听懂你说的,你能把问题解释清楚一点吗? I don't get the main menu header 是什么意思?
    • 必须是这样的
    • test
      • boo
    • 但是我现在没有得到“测试”
  • @Reshad $value for sub-menus 是一个数组,如果test应该是URL地址,$value应该是子菜单项,子菜单在哪里菜单标题??子菜单的标题中是否有链接?还是test是子菜单的标题?
  • 【解决方案3】:

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

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

    【讨论】:

    • 不要使用另一个foreach,而是进行递归调用!
    【解决方案4】:

    试试这个

    <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>
    

    【讨论】:

      【解决方案5】:
      $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>
      

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签