我正在尝试使用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>
当前输出:(非常混乱。警告,哈哈)
<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));
这是我的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>
答案 0 :(得分: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
类似的内容。
答案 1 :(得分: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);
答案 2 :(得分: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>