views:

3269

answers:

3

This should (hopefully) be a pretty easy question for some of you to answer.

I have a working Recursive menu from a mySQL database, now my main problem is:

What is the best way to create the URL? I would prefer to bring in the title of each row like /eggs/milk/bacon/. Eggs being level 0 like: eggs-0, milk-1, bacon-2. Any ideas on how to dynamicly output this?

I am pretty much going for what "cletus" said a few comments down on this question: http://stackoverflow.com/questions/477793/php-mysql-building-a-nav-menu-hierarchy

But I need a bit more explanation on how to do it.

+2  A: 

Unless you plan to modify your menu tree often, pre-storing the required hierarchical URL for each menu item is probably the easiest (for run-time resolution that is).

If you expect the tree to be modified often enough, lets say - through a web interface, then it would be easier to generate the paths every time you read the menu, something like this:

 id | name   | parent
----+--------+-------
 0  | eggs   | NULL
 1  | milk   | 0
 2  | bacon  | 1
 3  | tomato | 0
 4  | lettuce| 1

foreach (query("SELECT * FROM menu ORDER BY parent ASC") as $row) {
  $menuitem = array_merge(array(), $row);
  $menuLookup[$menuitem['id']] &= $menuitem;
  if ($menuitem['parent'] == null) {
    $menuitem['path'] = "/" . $menuitem['name'];
    $menu[] &= $menuitem[];
  } else {
    $parent &= $menuLookup[$menuitem['parent']];
    $menuitem['path'] = $parent['path'] . "/" . $menuitem['name'];
    $parent['menu'][] &= $menuitem;
  }
}

I haven't debugged this code, only tested it for correctness ;-)

Guss
I should of stated that I'm not a php pro but from what I can tell you are basically saying "If 'parent' exists then put 'name' into the parent['path'] array and move on? So this would eventually lead to /milk/bacon/ etc?
Davy
not exactly - $menu would eventually hold a hierarchy of menu items by placing children into the 'menu' array of their parent. This is standard "un-flatten my list" stuff.
Guss
The only gimmick here is composing 'path' by prefixing the current name with the parent's 'path', there by recursively building each child's path from the sum of its parents.
Guss
Awesome, thanks for the help! I will see what I can do. I am still learning how to properly use arrays, I was trying to just use a variable to "stack" the path values recursively. But obviously it would just be overwriting itself (I think, haha!).
Davy
Guss
+4  A: 

Well, if you want a hierarchy, be best method I know of is called "Modified Preorder Tree Traversal" that is described in great detail in this Sitepoint article, starts about halfway down.

The main difference from what Guss suggested is that it's a bit more performant and a lot easier to only fetch the part of the tree you're looking for.

mikl
Thanks for the info! I did check out both methods before starting this project however the most rows I would be dealing with is 75 max so Tree Traversal seemed like overkill. However, I am now seeing that Tree traversal would of given me a bit more control. *le sigh.*
Davy