在PHP中创建菜单列表:从嵌套列表到多维数组并返回

在PHP中创建菜单列表:从嵌套列表到多维数组并返回,php,list,drop-down-menu,multidimensional-array,twitter-bootstrap-3,Php,List,Drop Down Menu,Multidimensional Array,Twitter Bootstrap 3,我必须从可能的子列表中创建一个菜单。 从一个简单的例子中,我想创建一个兼容的引导菜单 从这样的代码中: <ul> <li>Link 1</li> <li>Link 2 <ul> <li>Sublink A</li> <li>Sublink B</li> </ul> </li> <li>Link 3

我必须从可能的子列表中创建一个菜单。 从一个简单的例子中,我想创建一个兼容的引导菜单 从这样的代码中:

<ul>
  <li>Link 1</li>
  <li>Link 2
    <ul>
      <li>Sublink A</li>
      <li>Sublink B</li>
    </ul>
  </li>
  <li>Link 3
    <ul>
      <li>Sublink C</li>
    </ul>
  </li>
</ul>
最后,找回这个:

<ul class="nav navbar-nav">
  <li><a class="primary" href="link_1.html">Link 1</a></li>
  <li class="dropdown">
    <a href="#" class="primary dropdown-toggle" data-toggle="dropdown">Link 2</a>
    <ul class="dropdown-menu">
      <li><a href="sublink_a.html">Sublink A</a></li>
      <li><a href="sublink_b.html">Sublink B</a></li>
    </ul>
  </li>
  <li class="dropdown">
    <a href="#" class="primary dropdown-toggle" data-toggle="dropdown">Link 3</a>
    <ul class="dropdown-menu">
      <li><a href="sublink_c.html">Sublink C</a></li>
    </ul>
  </li>
</ul>
条件是: 如果
  • 有子项has href=“#”,则将类下拉列表添加到gle和数据切换=“dropdown”; 孩子有类“下拉菜单”; 如果
  • 没有父级,则将类“primary”添加到

    我使用这段代码,但它仅用于简单列表,而不是嵌套列表

    <?php
    $currentPage = "";
    $contents = "<ul>
      <li>Link 1</li>
      <li>Link 2</li>
      <li>Link 3</li>
    </ul>";
    
    // remove width, height, style
    $contents = preg_replace('/(width|height|style|target)="[^"]+"/i', "", $contents);
    // remove spaces form li
    $contents = str_replace(array('<li >',' <li >'),"<li>",$contents);
    // remove ul/ol tag and tabs
    $contents = str_replace(array('\t','<ul>','<ul >','</ul>','<ol>','<ol >','</ol>'),"",$contents);
    $arrNavTopList = explode("\n",trim($contents));
    echo "<h4>Array:</h4>\n";
    print_r($arrNavTopList);
    echo "<hr>\n<h4>List:</h4>\n";
    $totNavTopList = count($arrNavTopList);
    if($totNavTopList>0){
      echo '<ul class="nav navbar-nav">'."\n";
      $countNtL=1;
      foreach($arrNavTopList as $pagename) {
        $pagename = str_replace("\t","",$pagename);
        preg_match_all("(<li>(.*?)</li>)", $pagename, $arrLinkList);
        $linktopage = $arrLinkList[1][0];
        if(
          strtolower($linktopage)==strtolower(str_replace("_"," ",$currentPage)) ||
          strtolower($linktopage)=="home" && !(strpos($currentPage,"^")===FALSE)
        ) {
          $active=' class="active"';
        } else {
          $active='';
        }
        echo '<li'.$active.'>';
        if (strstr($linktopage,"http") || strstr($linktopage,"target")) {
          $linktopage = preg_replace('/(style|target)="[^"]+"/i', "", $linktopage);
          $linktopage = str_replace('<a','<a rel="external nofollow" class="_blank"',$linktopage);
          echo $linktopage;
        } else {
          if(strtolower($linktopage)=="home" || strtolower($linktopage)=="home page") {
            echo '<a href="/">'.htmlentities($linktopage).'</a>';
          } else {
            echo '<a href="'.str_replace(" ","_",strtolower($linktopage)).'">'.htmlentities($linktopage).'</a>';
          }
        }
        echo '</li>'."\n";
        $countNtL++;
      }
      echo '</ul>'."\n";
    }
    ?>
    

    正如@Soundz所提到的,在发布此类问题之前,你必须做更多的工作,有很多方法可以实现你想要的。我会将嵌套foreach与preg_match或类似的东西一起使用。@Johnride这是一个多么好的方式来表达我仅有的苛刻的词语。主题:一个可以组装它的对象怎么样?至少试试吧,不要偷懒,这里没有人为任何人编写完整的代码,不知何故我会使用递归性。我写了一个代码,可以更改带有链接的列表中的简单列表,但我需要一些不同的东西。这就是为什么我问这里没有张贴任何类型的代码。我没有执行额外步骤的代码,也不想写太多关于请求的内容。
    
    <?php
    $currentPage = "";
    $contents = "<ul>
      <li>Link 1</li>
      <li>Link 2</li>
      <li>Link 3</li>
    </ul>";
    
    // remove width, height, style
    $contents = preg_replace('/(width|height|style|target)="[^"]+"/i', "", $contents);
    // remove spaces form li
    $contents = str_replace(array('<li >',' <li >'),"<li>",$contents);
    // remove ul/ol tag and tabs
    $contents = str_replace(array('\t','<ul>','<ul >','</ul>','<ol>','<ol >','</ol>'),"",$contents);
    $arrNavTopList = explode("\n",trim($contents));
    echo "<h4>Array:</h4>\n";
    print_r($arrNavTopList);
    echo "<hr>\n<h4>List:</h4>\n";
    $totNavTopList = count($arrNavTopList);
    if($totNavTopList>0){
      echo '<ul class="nav navbar-nav">'."\n";
      $countNtL=1;
      foreach($arrNavTopList as $pagename) {
        $pagename = str_replace("\t","",$pagename);
        preg_match_all("(<li>(.*?)</li>)", $pagename, $arrLinkList);
        $linktopage = $arrLinkList[1][0];
        if(
          strtolower($linktopage)==strtolower(str_replace("_"," ",$currentPage)) ||
          strtolower($linktopage)=="home" && !(strpos($currentPage,"^")===FALSE)
        ) {
          $active=' class="active"';
        } else {
          $active='';
        }
        echo '<li'.$active.'>';
        if (strstr($linktopage,"http") || strstr($linktopage,"target")) {
          $linktopage = preg_replace('/(style|target)="[^"]+"/i', "", $linktopage);
          $linktopage = str_replace('<a','<a rel="external nofollow" class="_blank"',$linktopage);
          echo $linktopage;
        } else {
          if(strtolower($linktopage)=="home" || strtolower($linktopage)=="home page") {
            echo '<a href="/">'.htmlentities($linktopage).'</a>';
          } else {
            echo '<a href="'.str_replace(" ","_",strtolower($linktopage)).'">'.htmlentities($linktopage).'</a>';
          }
        }
        echo '</li>'."\n";
        $countNtL++;
      }
      echo '</ul>'."\n";
    }
    ?>
    
    <?php
    /**
     * Traverse an elements children and collect those nodes that
     * have the tagname specified in $tagName. Non-recursive
     *
     * @param DOMElement $element
     * @param string $tagName
     * @return array
     */
    
     //from: https://stackoverflow.com/a/3049677/1596547
    
    function getImmediateChildrenByTagName(DOMElement $element, $tagName)
    {
        $result = array();
        foreach($element->childNodes as $child)
        {
            if($child instanceof DOMElement && $child->tagName == $tagName)
            {
                $result[] = $child;
            }
        }
        return $result;
    }
    
    $doc = new DOMDocument();
    $doc->loadHTML("<ul>
      <li>Link 1</li>
      <li>Link 2
        <ul>
          <li>Sublink A</li>
          <li>Sublink B</li>
        </ul>
      </li>
      <li>Link 3
        <ul>
          <li>Sublink C</li>
        </ul>
      </li>
    </ul>");
    
    //from: https://stackoverflow.com/a/6953808/1596547
    # remove <!DOCTYPE 
    $doc->removeChild($doc->firstChild);            
    
    # remove <html><body></body></html> 
    $doc->replaceChild($doc->firstChild->firstChild->firstChild, $doc->firstChild);
    
    $elements = $doc->getElementsByTagName('ul');
    $parentitems = getImmediateChildrenByTagName($elements->item(0),'li');
    $elements->item(0)->setAttribute ('class' , 'nav navbar-nav');
    foreach ($parentitems as $parentitem)
    {
        if($parentitem->childNodes->length > 1) {
    
            $parentitem->setAttribute ('class' , 'dropdown' );
            $link = $doc->createElement('a',$parentitem->childNodes->item(0)->nodeValue);
            $link->setAttribute ('class' , 'primary dropdown-toggle' );
            $link->setAttribute ('href' , '#');
            $link->setAttribute ('data-toggle','dropdown');
            //$parentitem->nodeValue = null; 
            $old = $parentitem->childNodes->item(0);
            $parentitem->replaceChild($link,$old);
    
            $parentitem->childNodes->item(1)->setAttribute ('class' , 'dropdown-menu' );
            $submenuitems = getImmediateChildrenByTagName($parentitem->childNodes->item(1),'li');
    
            foreach($submenuitems as $submenuitem)
            {
                $link = $doc->createElement('a',$submenuitem->nodeValue);
                $link->setAttribute ('href' , $submenuitem->childNodes->item(0)->nodeValue.'.html');
                $submenuitem->nodeValue = null; 
                $submenuitem->appendChild($link);
            }   
    
    
        }
        else 
        {
            $link = $doc->createElement('a',$parentitem->nodeValue);
            $link->setAttribute ('class' , 'primary' );
            $link->setAttribute ('href' , $parentitem->childNodes->item(0)->nodeValue.'.html');
            $parentitem->nodeValue = null; 
            $parentitem->appendChild($link);
        }
    
    
    }   
    
    echo $doc->saveHTML();