PHP/MySQL - 构建导航菜单层次结构

发布于 2024-07-12 07:13:50 字数 997 浏览 11 评论 0原文

因此,最终的菜单将如下所示:

Item B
    Item B-1
        Item B-1-2
        Item B-1-1
Item A
    SubItem A-1
    SubItem A-2
Item C

基于以下数据库记录:

id        menu_title          parent_menu_id    menu_level    weight
1         Item A                0                           1                     1
2         Item B                0                           1                     0
3         Item C                0                           1                     2
4         SubItem A-2       1                           2                     1
5         Item B-1             2                           2                     0
6         Item B-1-1          5                           3                     1
7         SubItem A-1       1                           2                     0
8         Item B-1-2          5                           3                     0

我将如何显示? 我的猜测是它将涉及将所有项目存储到多维数组中,然后循环遍历它以某种方式...

So the final menu will look something like this:

Item B
    Item B-1
        Item B-1-2
        Item B-1-1
Item A
    SubItem A-1
    SubItem A-2
Item C

Based on the following DB records:

id        menu_title          parent_menu_id    menu_level    weight
1         Item A                0                           1                     1
2         Item B                0                           1                     0
3         Item C                0                           1                     2
4         SubItem A-2       1                           2                     1
5         Item B-1             2                           2                     0
6         Item B-1-1          5                           3                     1
7         SubItem A-1       1                           2                     0
8         Item B-1-2          5                           3                     0

How would I go about displaying? My guess is it'll involve storing all the items into a multidimensional array, then looping through it somehow...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

拥有 2024-07-19 07:13:50

分层数据在关系数据库中有些烦人(不包括 Oracle,它在 START WITH/CONNECT BY 中有运算符来处理这个问题)。 基本上有两种模型:邻接列表和嵌套集。

您选择了邻接集,这也是我通常所做的。 尽管可以在单个查询中以正确的顺序检索嵌套集模型,但它比嵌套集模型更容易更改。 邻接表不能。 您需要构建一个中间数据结构(树),然后将其转换为列表。

我会做的(事实上最近已经做了)是:

  • 在一个按父 ID 排序的查询中选择整个菜单内容;
  • 使用关联数组或类/对象构建菜单结构树;
  • 遍历该树以创建嵌套的无序列表; 并
  • 使用 Superfish 等 jQuery 插件将该列表转换为菜单。

您可以构建如下所示的内容:

$menu = array(
  array(
    'name' => 'Home',
    'url' => '/home',
  ),
  array(
    'name' => 'Account',
    'url' => '/account',
    'children' => array(
      'name' => 'Profile',
      'url' => '/account/profile',
    ),
  ),
  // etc
);

并将其转换为:

<ul class="menu">;
  <li><a href="/">Home</a></li>
  <li><a href="/account">Account Services</a>
    <ul>
      <li><a href="/account/profile">Profile</a></li>
...

用于生成菜单数组的 PHP 相当简单,但解决起来有点棘手。 您使用递归树遍历函数来构建 HTML 嵌套列表标记,但将其实现留给读者作为练习。 :)

Hierarchical data is somewhat annoying in a relationsal database (excluding Oracle, which has operators in START WITH/CONNECT BY to deal with this). There are basically two models: adjacency list and nested sets.

You've chosen adjacency sets, which is what I typically do too. It's far easier to change than the nested set model, although the nested set model can be retrieved in the correct order in a single query. Adjacency lists can't be. You'll need to build an intermediate data structure (tree) and then convert that into a list.

What I would do (and have done recently in fact) is:

  • select the entire menu contents in one query ordered by parent ID;
  • Build a tree of the menu structure using associative arrays or classes/objects;
  • Walk that tree to create nested unordered lists; and
  • Use a jQuery plug-in like Superfish to turn that list into a menu.

You build something like this:

$menu = array(
  array(
    'name' => 'Home',
    'url' => '/home',
  ),
  array(
    'name' => 'Account',
    'url' => '/account',
    'children' => array(
      'name' => 'Profile',
      'url' => '/account/profile',
    ),
  ),
  // etc
);

and convert it into this:

<ul class="menu">;
  <li><a href="/">Home</a></li>
  <li><a href="/account">Account Services</a>
    <ul>
      <li><a href="/account/profile">Profile</a></li>
...

The PHP for generating the menu array from is reasonably straightforward but a bit finnicky to solve. You use a recursive tree-walking function that builds the HTML nested list markup but will leave it's implementation as an exercise for the reader. :)

演多会厌 2024-07-19 07:13:50

处理现有的数据结构通常会涉及递归或多个查询来构建树。

您是否考虑过存储层次结构的其他方法? 查看修改后的预购遍历 - 这是一篇关于此的很好的 基于 PHP 的文章

Dealing with the data structure as you have it will often involve recursion or multiple queries to build the tree.

Have you considered other ways of storing a hierarchy? Check out modified pre-order traversal - here's a nice PHP based article about this.

英雄似剑 2024-07-19 07:13:50

我刚刚在类似的问题中发布了我自己的将 MySQL 分层数据(邻接列表)转换为菜单(HTML)的方法,

使用递归。 它需要对数据库进行单个查询

欲了解更多信息,请访问

https://stackoverflow.com/questions/2871861#3368622

谢谢。

I just posted in a similar question my own approach to transform MySQL hierarchical data (adjacency list) into a menu (HTML)

It does not use recursion. And it requires a single query to the database.

Read more at

https://stackoverflow.com/questions/2871861#3368622

Thanks.

琉璃梦幻 2024-07-19 07:13:50

您存储分层数据的方式并不像您希望的那样有效。 几年前我读过这篇文章 管理 MySQL 中的分层数据并且后来发现它是在 SQL 中管理基于层次结构的数据的最佳解决方案。 下一个最大的好处是我相信您可以通过一个查询来获取整个树。

The way your storing hierarchical data isn't as efficient as you might want. I read the article Managing Hierarchical Data in MySQL a few years ago and have since found it as the best solution to managing hierarchy based data in SQL. Next best benefit is that I believe you can grab the entire tree with one query.

黑白记忆 2024-07-19 07:13:50

如果您不想使用嵌套集,则可以生成层次结构的另一种简单方法是在前面使用简单的文本字符串。

Item B
    Item B-1
        Item B-1-2
        Item B-1-1
Item A
    SubItem A-1
    SubItem A-2
Item C

会变成

1 Item B
  1.1 Item B1
    1.1.1 Item B11
    1.1.2 Item B12
2 Item A
  2.1 Item A1
  2.2 Item B2
3 Item C

每个项目前面的数字可以存储在一个字段中,并根据长度(表示它所在的深度)进行解析,以告诉您需要了解的有关它去向的所有信息。

我使用嵌套集合层次结构来处理需要计算的更复杂的东西,但我发现这种方法效果很好

Another simple way you can generate hierarchy if you don't want to use nested sets is to use a simple text string in front.

Item B
    Item B-1
        Item B-1-2
        Item B-1-1
Item A
    SubItem A-1
    SubItem A-2
Item C

Would become

1 Item B
  1.1 Item B1
    1.1.1 Item B11
    1.1.2 Item B12
2 Item A
  2.1 Item A1
  2.2 Item B2
3 Item C

The digit in front of each item could be stored in a field and parsed based on length (representing the depth of where it is) to tell you everything you need to know about where it goes.

I use nested set hierarchies for more complicated stuff that requires calculation,e tc, but I find this approach has served well

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文