图层导航菜单

时间:2013-08-10 03:29:50

标签: php mysql

我有3个表,top_category,bottom_category,产品,目前我已经列出了top_category,我很困惑如何处理列出第二个类别,但是让它列出所以它知道它所属的top_category,这就是为什么我有外键父,所以如果top_category例如是:

prod1 
prod2
prod3
etc

现在我想将我的底层类别加载到这些top_categories中:

prod1
 -subprod1
 -subprod2
 -subprod3
prod2
 -subprod4
 -subprod5
prod3
 -subprod6
etc

这是我的数据库:

CREATE TABLE top_category (
  id INT PRIMARY KEY,
  NAME VARCHAR(100) 
);

CREATE TABLE bottom_category (
  id INT PRIMARY KEY,
  NAME VARCHAR(100) ,
  top_category_id INT REFERENCES top_category
);

create table product (
  id int primary key,
  name varchar(100) ,
  bottom_category_id int references bottom_category
);

这是我的php& HTML代码:

<?php
include('dbconnect.php'); 

try
    { 
        $result = $pdo->query(" SELECT * FROM top_category ORDER BY top_name ASC; ");
    } // end try
    catch (PDOException $e) 
    { 
        echo 'There was a error fetching the products.' . $e->getMessage();
        exit(); 
    } // end catch

$products = array();

foreach ($result as $row)
{
    $products[] = array('id' => $row['id'],    
                        'top_name' => $row['top_name']);
}

?>

<div class="sidebar">
    <h4 class="sidebar-header">Select Products</h4>
    <form class="nav-search-form">
        <input type="search" name="search" placeholder="Search products">
    </form>
    <nav class="sidebar-links"> 
        <ul>
            <li><a id="red" href="index.php">New Products</a></li>
            <?php foreach ($products as $product): ?>
            <li><a href="#"><?php echo htmlspecialchars($product['top_name']);?></a>

            <?php endforeach; ?>    
                <ul>
                    <li><a href="#"></a></li>
                </ul>
            </li>   
        </ul>
    </nav>
</div><!-- sidebar -->
<div class="main-content">

1 个答案:

答案 0 :(得分:0)

您应该将top_categorybottom_category表合并到一个表中,可能是category。这些都不需要分开。它看起来像这样:

CREATE TABLE category (
  id INT PRIMARY KEY,
  parent_id INT,
  NAME VARCHAR(100) 
);

对于所有“热门”类别,parent_id将为0.对于任何“底部”类别,parent_id将是“{1}}”的“顶级”类别。下降。除了稍微清理数据库之外,如果需要,它还允许将来扩展到不止两层。

然后你创建一个递归函数(一个自己调用的函数)来循环并显示菜单结构,如下所示:

id

然后要显示您的菜单,您只需打印该功能的结果:

function menus( $parent_id, $pdo ) {
    $menu_query = "SELECT * FROM category WHERE parent_id = :parent_id";
    $menu_result = $pdo->prepare( $menu_query );
    $menu_result->execute( array( ":parent_id" => $parent_id ));

    $menu = "";
    if( $menu_result->rowCount() ) {
        $menu .= "<ul>\n";

        while( $menu_row = $menu_result->fetch( PDO::FETCH_ASSOC )) {
            $menu .= "<li>{$menu_row['NAME']}\n";
            $menu .= menus( $menu_row['id'], $pdo );
            $menu .= "</li>\n";
        }

        $menu .= "</ul>\n";
    }

    return $menu;
}

它将返回一个基本上如下的结构:

print menus( 0, $pdo );

(为了便于阅读而添加了缩进,上面的代码没有添加缩进,但这就是结构)。

这基本上就是这样做的。该函数提取所有顶级条目,然后当它循环遍历每个条目时,它调用自身,但是使用当前所选条目的ID,然后拉动所有子项,并执行相同的操作。每次完成一个图层(即为给定级别的所有条目创建结构)时,它会将该图形返回给父函数并连接数据。

我没有测试过这个特定的代码,因此它可能包含一个小问题,但这个概念很可靠(我自己实现了很多次)。

更新(样式)

如果要将样式应用于此菜单,其中每个图层都有不同的样式集,有两种方法可以执行此操作。第一个是函数的$ level变量,因此它的定义如下:

<ul>
  <li>prod1
    <ul>
      <li>subprod1</li>
      <li>subprod2</li>
      <li>subprod3</li>
    </ul>
  </li>
  <li>prod2
    <ul>
      <li>subprod4</li>
      <li>subprod5</li>
    </ul>
  </li>
  <li>prod3
    <ul>
      <li>subprod6</li>
    </ul>
  </li>
</ul>

首先通过function menus( $parent_id, $pdo, $level ) 调用该级别,然后在函数内使用0调用它。这样,将使用正确的值调用每个连续的级别。您可以根据此类创建类,例如$level + 1,然后将元素定义为level-1

第二种方法是将整个事物包装在class="level-{$level}"中,然后使用直接子选择器来引用特定级别。 <div>将是div>ul>li的第一个级别,<li>将是div>ul>li>ul>li的第二个级别,依此类推。