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


Creating menu list in PHP: from nested list to multidimensional array and return

>我必须从包含可能子列表的列表创建一个菜单。从一个简单的我想创建一个兼容的引导菜单所以从这样的代码:

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

我必须创建这个:

array(
  [0] => array(
    [id]       => 1,
    [nome]  => 'Link 1',
    [parent] => NULL,
  ),
  [1] => array(
    [id]       => 2,
    [nome]  => 'Link 2',
    [parent] => NULL,
  ),
  [2] => array(
    [id]       => 3,
    [nome]  => 'Sublink A',
    [parent] => 2
  ),
  [3] => array(
    [id]       => 4,
    [nome]  => 'Sublink B',
    [parent] => 2
  ),
  [4] => array(
    [id]       => 5,
    [nome]  => 'Link 3',
    [parent] => NULL
  ),
  [5] => array(
    [id]       => 6,
    [nome]  => 'Sublink C',
    [parent] => 3
  )
)  

最后,找回这个:

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

条件是:如果有

  • 孩子有 href="#",添加类下拉列表-toogle 和数据切换="下拉列表";孩子有类"下拉菜单";如果没有,请将
  • 类"主要"添加到

    我使用此代码,但它仅适用于简单列表,而不是嵌套列表。

    <?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();
    

    使用的其他答案:

    • https://stackoverflow.com/a/6953808/1596547
    • https://stackoverflow.com/a/3049677/1596547