使用递归构建动态Mega菜单?

Mik*_*ike 6 php recursion

我正在尝试使用PHP创建一个Mega菜单,我在使结构正确输出时遇到问题.我已经对Mega菜单进行了硬编码以测试所有内容并且工作正常,但显然我需要PHP来为我创建它.

我有一个硬编码的Mega菜单示例,所以每个人都可以看到我正在尝试创建的内容:

http://www.libertyeaglearms.com/dev

或者这是代码:

期望的输出:

    <div id="wrapper">
        <ul class="mega-menu">
            <li class="mega-menu-drop">
                <a href="#">Firearms</a>
                 <div class="mega-menu-content">
                     <div class="column">
                         <h4>Rifles</h4>
                          <ul>
                              <li><a href="#">One</a></li>
                              <li><a href="#">Two</a></li>
                              <li><a href="#">Three</a></li>
                              <li><a href="#">Four</a></li>
                              <li><a href="#">Five</a></li>
                          </ul>
                      </div>
                      <div class="column">
                          <h4>Handguns</h4>
                          <ul>
                              <li><a href="#">One</a></li>
                              <li><a href="#">Two</a></li>
                              <li><a href="#">Three</a></li>
                              <li><a href="#">Four</a></li>
                              <li><a href="#">Five</a></li>
                          </ul>
                      </div>
                      <div class="column">
                          <h4>Shotguns</h4>
                          <ul>
                              <li><a href="#">One</a></li>
                              <li><a href="#">Two</a></li>
                              <li><a href="#">Three</a></li>
                              <li><a href="#">Four</a></li>
                              <li><a href="#">Five</a></li>
                          </ul>
                      </div>
                  </div>
              </li>
              <li class="mega-menu-drop">
                  <a href="#">Archery</a>
                  <div class="mega-menu-content">
                      <div class="column">
                          <h4>Bows</h4>
                          <ul>
                              <li><a href="#">One</a></li>
                              <li><a href="#">Two</a></li>
                              <li><a href="#">Three</a></li>
                              <li><a href="#">Four</a></li>
                              <li><a href="#">Five</a></li>
                          </ul>
                      </div> 
                      <div class="column">
                          <h4>Arrows</h4>
                          <ul>
                              <li><a href="#">One</a></li>
                              <li><a href="#">Two</a></li>
                              <li><a href="#">Three</a></li>
                              <li><a href="#">Four</a></li>
                              <li><a href="#">Five</a></li>
                          </ul>
                      </div>
                  </div>
              </li> 
          </ul>
      </div>
Run Code Online (Sandbox Code Playgroud)

当前输出:(非常混乱.警告,哈哈)

<div id="wrapper">
    <ul class="mega-menu">
    <li class="mega-menu-drop">
            <a href="#">archery</a>
            <div class="mega-menu-content">
                <div class="column">
                    <h4>compound</h4>
            <ul>
            <h4>bows</h4>
            <ul>
            </div>
        </li>
        <li class="mega-menu-drop">
            <a href="#">firearms</a>
            <div class="mega-menu-content">
                <div class="column">
                    <h4>rifle ammunition</h4>
                    <ul>
            <h4>ammunition</h4>
                    <ul>
            </div>
        </li>
            </ul>  
        </div>
Run Code Online (Sandbox Code Playgroud)

这是我的PHP:

$json = json_decode($category->buildDepartments(NULL),true);
function buildDepartments($array,$parent)
{
    $html = '';                 
    foreach($array as $category)
    {
        if($category['parent'] == $parent)
        {
             if($category['parent'] == NULL)
             {
                 $html .= '<li class="mega-menu-drop">' . "\n\t\t\t\t";
                 $html .= '<a href="#">'.$category['category_name'].'</a>' . "\n\t\t\t\t";
                 $html .= '<div class="mega-menu-content">' . "\n\t\t\t\t\t";                            
                 $html .= '<div class="column">' . "\n\t\t\t\t\t\t";
                 $html .= buildDepartments($array,$category['category_id']);                            
                 $html .= '</div>' . "\n\t\t\t";
                 $html .= '</li>' . "\n\t\t\t";
              }
              else
              {
                  $html .= buildDepartments($array,$category['category_id']);
                  $html .= '<h4>'.$category['category_name'].'</h4>' . "\n\t\t\t\t\t\t";
                  $html .= '<ul>' . "\n\t\t\t\t";

               }                        
          }
    }
    return $html;
}
print(buildDepartments($json,NULL));
Run Code Online (Sandbox Code Playgroud)

这是我的DATABSE:

在此输入图像描述

在BOUNTY之后编辑

建立icktoofay建议的东西,我似乎无法弄清楚foreach()循环.我得到的问题是,当我看到类别和子类别时,我会在大型菜单中获得部门名称.我认为问题是我需要执行一个具有特定父ID的循环以获得所有孩子,但我不确定这是否是问题所在.这是代码:

<div id="wrapper">
<ul class="mega-menu">         
    <?php $json = json_decode($category->buildDepartments(NULL)); ?>
    <?php foreach($json as $category): ?>
        <li class="mega-menu-drop">
            <a href="#"><?php if($category->parent === NULL){echo $category->category_name;} ?></a>
            <div class="mega-menu-content">                 
                <?php foreach($category as $subcategory): ?>
                <div class="column">
                    <?php if($category->category_id === $category->parent){echo '<h4>' . $category->category_name . '</h4>';}?>
                    <ul>
                        <?php foreach($category as $subcategory)
                        {
                            echo '<li>' . $category->category_name . '</li>';
                        }
                        ?>
                    </ul>
                </div>
                <?php endforeach; ?>                   
            </div>
        </li>
     <?php endforeach; ?>  
</ul>  
</div>
Run Code Online (Sandbox Code Playgroud)

ick*_*fay 8

由于它是固定深度并且每个级别的格式不同,因此递归可能不合适.此外,将所有内容放在字符串中是不优雅的.相反,您可能想尝试编织HTML并循环在一起,如下所示:

<div id="wrapper">
    <ul class="mega-menu">
        <?php foreach($categories as $category): ?>
            <li class="mega-menu-drop">
                <a href="#"><?php echo $category->name; ?></a>
                <div class="mega-menu-content">
                    <?php foreach($category->subcategories as $subcategory): ?>
                        <!-- and so on -->
                    <?php endforeach; ?>
                </div>
            </li>
        <?php endforeach; ?>
    </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

我在这里使用的代码假设你已经从一个平面阵列到一个树状结构.例如,如果我们有一个Category班级:

class Category {
    public $id;
    public $parentID;
    public $name;
    public $parent;
    public $subcategories;

    public function __construct($id, $parentID, $name) {
        $this->id = $id;
        $this->parentID = $parentID;
        $this->name = $name;
        $this->parent = null;  // will be filled in later
        $this->subcategories = array();  // will be filled in later
    }
}
Run Code Online (Sandbox Code Playgroud)

像你可能从数据库调用(我们将调用$flatCategories)得到的一组关联数组,我们可以构建一堆未连接的Category实例,如下所示:

$categories = array();
foreach($flatCategories as $flatCategory) {
    $categories[$flatCategory['id']] =
        new Category($flatCategory['category_id'],
                     $flatCategory['parent'],
                     $flatCategory['category_name']);
}
Run Code Online (Sandbox Code Playgroud)

然后我们可以将它们全部连接成一个层级结构:

foreach($categories as $category) {
    if($category->parentID !== null) {
        $category->parent = $categories[$category->parentID];
        $category->parent->subcategories[] = $category;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在他们都联系起来,我们只关心保持对根的引用:

$roots = array();
// This could, of course, be merged into the last loop,
// but I didn't for clarity.
foreach($categories as $category) {
    if($category->parentID === null) {
        $roots[] = $category;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在$roots包含所有根类别,遍历非常简单.在我的顶部示例中,我假设$categories有类似$roots的内容.