6

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

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

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>

当前输出:(非常混乱。被警告,大声笑)

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

这是我的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));

这是我的数据库:

在此处输入图像描述

赏金后编辑

根据 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>
4

3 回答 3

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>

我在这里使用的代码假设您已经将它从一个平面数组排序到一个树状结构。例如,如果我们有一个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
    }
}

还有一个关联数组的数组,就像您可能从数据库调用(我们将调用它$flatCategories)中获得的一样,我们可以构建一堆尚未连接的Category实例,如下所示:

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

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

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

现在它们都连接起来了,我们只关心保留对根的引用:

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

现在$roots包含所有根类别,并且遍历起来相当简单。在顶部的示例中,我假设其中$categories有类似$roots的东西。

于 2013-03-31T05:45:30.013 回答
4

您需要生成称为超级树的东西并使用递归函数来回显每个分支,这将允许无限深度树,但是它也允许未知深度树。

一、SQL:

SELECT category_id, parent, category_name

二、使用SQL创建树:

$super_tree = array();
while(($row = mysql_fetch_assoc($res)) != NULL) {
  $parent = $row['parent'] == NULL ? 0 : $row['parent']; //clean up the parent

  $super_tree[$parent][$row['category_id']] = $row['category_name'];
}

三、回声出树

function echo_branch($tree_branch, $tree_root) {
  echo("<ul>\n"); //open up our list for this branch

  foreach($tree_branch as $id => $name) { //foreach leaf on the branch
    echo("<li>"); //create a list item

    echo("<a href=\"#{$id}\">{$name}</a>"); //echo out our link

    if(!empty($tree_root[$id])) { //if our branch has any sub branches, echo those now
      echo_branch($tree_root[$id], $tree_root); //pass the new branch, plus the root
    }

    echo("</li>\n"); //close off this item
  }
  echo("</ul>\n"); //close off this list
}

echo_branch($super_tree[0], $super_tree); //echo out unlimited depth tree structure

这允许树结构的无限深度,并允许简单的代码能够在代码库中创建结构。

您现在需要做的就是在正确的位置添加额外的内容,例如类和额外的 html 元素。

如果您希望跟踪树的当前深度以便能够根据深度回显不同的内容,您可以进行以下更改

在函数定义中

function echo_branch($tree_branch, $tree_root, $depth) {

在 if 内的递归调用中

echo_branch($tree_root[$id], $tree_root, $depth++);

在最初的通话中

echo_branch($super_tree[0], $super_tree, 0);
于 2013-04-06T16:09:46.133 回答
0

看起来你正在使用变量

$category 

什么时候应该使用

$subcategory

试试这个:

<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($subcategory->category_id === $category->parent){echo '<h4>' . $category->category_name . '</h4>';}?>
                    <ul>
                        <?php foreach($subcategory as $subcategory2)
                        {
                            echo '<li>' . $subcategory2->category_name . '</li>';
                        }
                        ?>
                    </ul>
                </div>
                <?php endforeach; ?>                   
            </div>
        </li>
     <?php endforeach; ?>  
</ul>  
</div>
于 2013-04-12T20:47:04.680 回答