0

我有一个数组,我在其中保留了一个包含 100 多个元素的菜单,然后将其打印为 CSS 下拉菜单。有 5 个主菜单,它们有子菜单,其中一些有子菜单等。现在我在打印循环时对循环进行硬编码,但我相信一定有一些聪明的方法来做只需几行代码!这是数组开头的样子:

$menu = array(
    array(
        'title' => 'Travel tips',
        'url' => 'travel-tips',
        'sub' => array(
            array(
                'title' => 'Travel guide',
                'url' => 'travel-guide'),
            array(
                'title' => 'Places to visit',
                'url' => 'places-to-visit',
                'sub' => array(
                    array(
                        'title' => 'Ahu Akivi',
                        'url' => 'ahu-akivi'),
                    array(
                        'title' => 'Ahu Tongariki',
                        'url' => 'ahu-tongariki'),
                    array(
                        'title' => 'Anakena',
                        'url' => 'anakena'),
                    array(
                        'title' => 'Orongo',
                        'url' => 'orongo'),
                    array(
                        'title' => 'Rano Kau',
                        'url' => 'rano-kau'),
                    array(
                        'title' => 'Rano Raraku',
                        'url' => 'rano-raraku'),
                    array(
                        'title' => 'Vinapu',
                        'url' => 'vinapu'))),
            array(
                'title' => 'Things to do',
                'url' => 'things-to-do',
                'sub' => array(
                    array(
                        'title' => 'Beaches',
                        'url' => 'beaches'),
                    array(
                        'title' => 'Church',
                        'url' => 'church'),
                    array(
                        'title' => 'Fishing',
                        'url' => 'fishing'),

...然后它继续下去。如何在不对循环进行硬编码的情况下,仅在几行代码中递归地整齐干净地循环?

4

4 回答 4

2

如果您不想指定循环数,则需要一个自调用函数。只需在每个循环中添加您想要的 div/class/formatting。

function echoMenu($arr){
    foreach($arr as $subArr){
        if(!empty($subArr['sub'])){
            echo "<a href='{$subArr['url']}'>{$subArr['title']}</a>";
            echo "<div class='for-sub-links'>";
            echoMenu($subArr['sub']);
            echo "</div>";
        }else{
            echo "<div><a href='{$subArr['url']}'>{$subArr['title']}</a></div>";
        }   
    }
}
于 2013-08-29T20:35:20.173 回答
1
function recursive_menu($menu) {
  $output ='';
  foreach($menu as $m){
    $output .= '<li><a href="'.$m['url'].'">'.$m['title'].'</a>';
    if (isset($m['sub'])) {
      $output .= '<ul>';
      foreach( $m['sub'] as $item ) {
        $output.=recursive_menu($item);
      }
      $output .= '</ul>';
    } 
  }
  return $output.'</li>';  
}

然后...

echo '<ul>'.recursive_menu($menu).'</ul>';

像这样的东西......

于 2013-08-29T20:41:58.403 回答
1

相当简单 :

//mainly for demonstration / test purposes
function drawMenuItem($title, $url, $indent) {
    for ($i=0;$i<=$indent;$i++) echo "___";
    echo '<a href="'.$url.'">'.$title.'</a>'.'<br>';
}

//the actual "few lines of code recursively" function
function createMenuRecursively($menu, $indent) {
    foreach($menu as $menuItem){
        drawMenuItem($menuItem['title'], $menuItem['url'], $indent);
        if (is_array($menuItem['sub'])) {
            createMenuRecursively($menuItem['sub'], $indent+1);
        }
    }
}

createMenuRecursively($menu, 1);

$indent用于演示。覆盖drawMenuItemCSS/ ul/的li东西。以上输出:

在此处输入图像描述 覆盖

于 2013-08-29T20:50:59.140 回答
0

感谢 aynber,我想出了一个解决方案,它也提供了正确的 URL:

function echoMenu($arr, $prevURL)
{
    if (is_array($prevURL))
    {
        foreach($prevURL as $url) //Collect all previous URLs into string
            $prevURLStr .= $url . '/';
    }

    foreach($arr as $key => $subArr)
    {
        echo '<li><a href="/' . $prevURLStr . $subArr['url'] . '">' . $subArr['title'] . '</a>';
        if(!empty($subArr['sub'])) //Has submenu - call function again to enter it
        {
            $prevURL[] = $subArr['url']; //Add this folder's URL to array

            echo '<ul>';
            echoMenu($subArr['sub'], $prevURL);
            echo '</ul>';

            $prevURL = array_pop($prevURL); //Remove last element
            $prevURL = @array_values($prevURL); //Remove empty remains
        } 
        echo '</li>';
    }
}

echo '<ul class="menu">';

echoMenu($menu, null);

echo '</ul>';
于 2013-08-30T11:33:35.347 回答