9 Replies - 10627 Views - Last Post: 07 July 2010 - 06:45 PM Rate Topic: -----

#1 hadi_php  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 10
  • View blog
  • Posts: 382
  • Joined: 23-August 08

Whats the best way to make multi-level dynamic menu?

Posted 27 June 2010 - 12:04 PM

On Mysql

ID - Name - Parent
1 - Home - 0
2 - About- 0
3 - Sub1 - 1
4 - Sub2 - 1
5 - Sub3 - 3
6 - Sub4 - 1

Every Menu have ID, Name and Parent. ForSubMenu - ex[Sub1's parent is ID 1] So its Home's submenu

Query Part [Show From Mysql]

<?php
//Database Connection
echo "<ul>";
$query = mysql_query("SELECT * FROM menu WHERE parent=0");
while($row=mysql_fetch_object($query)) {

  echo "<li>";
  echo $row->name;
  //Showing Sub Level
  $query2 = mysql_query("SELECT * FROM menu WHERE parent='$row->id'");
  if(mysql_num_rows($query2)>0) {
  echo "<ul>";
    while($row2=mysql_fetch_object($query2)) {
      echo "<li>";
      echo $row2->name;
      echo "</li>";
    }
  echo "</ul>";
  }
  //Ends Sublevel
  echo "<li>";

}
echo "</ul>";
?>




but it is not the perfect solution though its works well. It may cause huge pressure on mysql while more sublevel needs to show. Which will be perfect way to show them?

Is This A Good Question/Topic? 0
  • +

Replies To: Whats the best way to make multi-level dynamic menu?

#2 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10390
  • View blog
  • Posts: 38,455
  • Joined: 27-December 08

Re: Whats the best way to make multi-level dynamic menu?

Posted 27 June 2010 - 12:09 PM

As this models after a Tree structure, you may find recursion to be helpful here. So basically, while you have rows with parent_id == current_id, select those rows with the appropriate parent_id's and repeat the proecss. Your base case here would be when you query and get 0 rows in your result set. So in order to use recursion, you'll want to define a function for this.
Was This Post Helpful? 0
  • +
  • -

#3 hadi_php  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 10
  • View blog
  • Posts: 382
  • Joined: 23-August 08

Re: Whats the best way to make multi-level dynamic menu?

Posted 28 June 2010 - 01:00 AM

Any example?
Was This Post Helpful? 0
  • +
  • -

#4 Fratyr  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 139
  • Joined: 10-April 08

Re: Whats the best way to make multi-level dynamic menu?

Posted 28 June 2010 - 01:28 AM

This helped me a lot: http://www.tommylacr...uilding-a-tree/
Was This Post Helpful? 1
  • +
  • -

#5 hadi_php  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 10
  • View blog
  • Posts: 382
  • Joined: 23-August 08

Re: Whats the best way to make multi-level dynamic menu?

Posted 28 June 2010 - 03:00 AM

I have
Array
(
    [0] => Array
        (
            [0] => 1
            [menu_id] => 1
            [1] => mainmenu
            [menu_type] => mainmenu
            [2] => 1
            [menu_default] => 1
            [3] => Menu one
            [menu_name] => Menu one
            [4] => menu-one
            [menu_sub_name] => menu-one
            [5] => 0
            [menu_parent_id] => 0
            [6] => 0
            [menu_section_id] => 0
            [7] => index.php?option=page&id=1
            [menu_link] => index.php?option=page&id=1
            [8] => 
            [menu_class] => 
            [9] => 1
            [menu_state] => 1
            [10] => 1
            [menu_ordering] => 1
            [11] => 2010-06-24 10:34:32
            [menu_created] => 2010-06-24 10:34:32
            [12] => 2010-06-24 11:02:21
            [menu_modified] => 2010-06-24 11:02:21
            [13] => page
            [link_type] => page
        )

    [1] => Array
        (
            [0] => 2
            [menu_id] => 2
            [1] => mainmenu
            [menu_type] => mainmenu
            [2] => 0
            [menu_default] => 0
            [3] => Menu two
            [menu_name] => Menu two
            [4] => menu-two
            [menu_sub_name] => menu-two
            [5] => 1
            [menu_parent_id] => 1
            [6] => 0
            [menu_section_id] => 0
            [7] => index.php?option=page&id=2
            [menu_link] => index.php?option=page&id=2
            [8] => 
            [menu_class] => 
            [9] => 1
            [menu_state] => 1
            [10] => 1
            [menu_ordering] => 1
            [11] => 2010-06-24 10:36:52
            [menu_created] => 2010-06-24 10:36:52
            [12] => 2010-06-24 17:35:49
            [menu_modified] => 2010-06-24 17:35:49
            [13] => page
            [link_type] => page
        )

    [2] => Array
        (
            [0] => 3
            [menu_id] => 3
            [1] => mainmenu
            [menu_type] => mainmenu
            [2] => 0
            [menu_default] => 0
            [3] => About
            [menu_name] => About
            [4] => about
            [menu_sub_name] => about
            [5] => 0
            [menu_parent_id] => 0
            [6] => 0
            [menu_section_id] => 0
            [7] => index.php?option=page&id=3
            [menu_link] => index.php?option=page&id=3
            [8] => 
            [menu_class] => 
            [9] => 1
            [menu_state] => 1
            [10] => 3
            [menu_ordering] => 3
            [11] => 2010-06-22 10:14:44
            [menu_created] => 2010-06-22 10:14:44
            [12] => 2010-06-24 10:57:36
            [menu_modified] => 2010-06-24 10:57:36
            [13] => page
            [link_type] => page
        )

    [3] => Array
        (
            [0] => 4
            [menu_id] => 4
            [1] => mainmenu
            [menu_type] => mainmenu
            [2] => 0
            [menu_default] => 0
            [3] => About us
            [menu_name] => About us
            [4] => about-us
            [menu_sub_name] => about-us
            [5] => 3
            [menu_parent_id] => 3
            [6] => 0
            [menu_section_id] => 0
            [7] => index.php?option=page&id=3
            [menu_link] => index.php?option=page&id=3
            [8] => 
            [menu_class] => 
            [9] => 1
            [menu_state] => 1
            [10] => 1
            [menu_ordering] => 1
            [11] => 2010-06-22 10:14:44
            [menu_created] => 2010-06-22 10:14:44
            [12] => 2010-06-24 10:57:49
            [menu_modified] => 2010-06-24 10:57:49
            [13] => page
            [link_type] => page
        )

    [4] => Array
        (
            [0] => 5
            [menu_id] => 5
            [1] => mainmenu
            [menu_type] => mainmenu
            [2] => 0
            [menu_default] => 0
            [3] => About company
            [menu_name] => About company
            [4] => about-company
            [menu_sub_name] => about-company
            [5] => 3
            [menu_parent_id] => 3
            [6] => 0
            [menu_section_id] => 0
            [7] => index.php?option=page&id=4
            [menu_link] => index.php?option=page&id=4
            [8] => 
            [menu_class] => 
            [9] => 1
            [menu_state] => 1
            [10] => 2
            [menu_ordering] => 2
            [11] => 2010-06-22 10:14:44
            [menu_created] => 2010-06-22 10:14:44
            [12] => 2010-06-24 10:58:20
            [menu_modified] => 2010-06-24 10:58:20
            [13] => page
            [link_type] => page
        )

    [5] => Array
        (
            [0] => 6
            [menu_id] => 6
            [1] => mainmenu
            [menu_type] => mainmenu
            [2] => 0
            [menu_default] => 0
            [3] => Menu Three
            [menu_name] => Menu Three
            [4] => menu-three
            [menu_sub_name] => menu-three
            [5] => 1
            [menu_parent_id] => 1
            [6] => 0
            [menu_section_id] => 0
            [7] => index.php?option=page&id=4
            [menu_link] => index.php?option=page&id=4
            [8] => 
            [menu_class] => 
            [9] => 1
            [menu_state] => 1
            [10] => 2
            [menu_ordering] => 2
            [11] => 2010-06-22 10:14:44
            [menu_created] => 2010-06-22 10:14:44
            [12] => 2010-06-24 10:57:14
            [menu_modified] => 2010-06-24 10:57:14
            [13] => page
            [link_type] => page
        )

    [6] => Array
        (
            [0] => 9
            [menu_id] => 9
            [1] => mainmenu
            [menu_type] => mainmenu
            [2] => 0
            [menu_default] => 0
            [3] => Menu Four
            [menu_name] => Menu Four
            [4] => menu-four
            [menu_sub_name] => menu-four
            [5] => 1
            [menu_parent_id] => 1
            [6] => 0
            [menu_section_id] => 0
            [7] => index.php?option=page&id=3
            [menu_link] => index.php?option=page&id=3
            [8] => 
            [menu_class] => 
            [9] => 1
            [menu_state] => 1
            [10] => 3
            [menu_ordering] => 3
            [11] => 2010-06-24 10:30:54
            [menu_created] => 2010-06-24 10:30:54
            [12] => 2010-06-21 19:35:09
            [menu_modified] => 2010-06-21 19:35:09
            [13] => page
            [link_type] => page
        )

    [7] => Array
        (
            [0] => 12
            [menu_id] => 12
            [1] => mainmenu
            [menu_type] => mainmenu
            [2] => 0
            [menu_default] => 0
            [3] => Weblink
            [menu_name] => Weblink
            [4] => weblink
            [menu_sub_name] => weblink
            [5] => 0
            [menu_parent_id] => 0
            [6] => 0
            [menu_section_id] => 0
            [7] => http://www.google.com
            [menu_link] => http://www.google.com
            [8] => 
            [menu_class] => 
            [9] => 1
            [menu_state] => 1
            [10] => 5
            [menu_ordering] => 5
            [11] => 2010-06-24 10:36:52
            [menu_created] => 2010-06-24 10:36:52
            [12] => 2010-06-24 10:52:47
            [menu_modified] => 2010-06-24 10:52:47
            [13] => external
            [link_type] => external
        )

    [8] => Array
        (
            [0] => 13
            [menu_id] => 13
            [1] => mainmenu
            [menu_type] => mainmenu
            [2] => 0
            [menu_default] => 0
            [3] => Blog
            [menu_name] => Blog
            [4] => blog
            [menu_sub_name] => blog
            [5] => 0
            [menu_parent_id] => 0
            [6] => 2
            [menu_section_id] => 2
            [7] => index.php?option=cat&id=2
            [menu_link] => index.php?option=cat&id=2
            [8] => 
            [menu_class] => 
            [9] => 1
            [menu_state] => 1
            [10] => 6
            [menu_ordering] => 6
            [11] => 2010-06-24 14:05:00
            [menu_created] => 2010-06-24 14:05:00
            [12] => 2010-06-24 14:05:00
            [menu_modified] => 2010-06-24 14:05:00
            [13] => section
            [link_type] => section
        )

    [9] => Array
        (
            [0] => 14
            [menu_id] => 14
            [1] => mainmenu
            [menu_type] => mainmenu
            [2] => 0
            [menu_default] => 0
            [3] => Multi
            [menu_name] => Multi
            [4] => multi
            [menu_sub_name] => multi
            [5] => 5
            [menu_parent_id] => 5
            [6] => 0
            [menu_section_id] => 0
            [7] => index.php?option=page&id=1
            [menu_link] => index.php?option=page&id=1
            [8] => 
            [menu_class] => 
            [9] => 1
            [menu_state] => 1
            [10] => 1
            [menu_ordering] => 1
            [11] => 2010-06-26 23:16:13
            [menu_created] => 2010-06-26 23:16:13
            [12] => 2010-06-28 08:08:28
            [menu_modified] => 2010-06-28 08:08:28
            [13] => page
            [link_type] => page
        )

)



Stored into a varible $a

Then
function mapTree($dataset) {
	$tree = array();
	foreach ($dataset as $id=>&$node) {
		if ($node['menu_parent_id']==0) {
			$tree[$id] = &$node;
		} else {
			if (!isset($dataset[$node['menu_parent_id']]['children'])) $dataset[$node['menu_parent_id']]['children'] = array();
			$dataset[$node['menu_parent_id']]['children'][$id] = &$node;
		}
	}
	
	return $tree;
}

function display_tree($nodes, $indent=0) {
	if ($indent >= 20) return;	// Stop at 20 sub levels
	
	foreach ($nodes as $node) {
		print str_repeat('&nbsp;',$indent*4);
		print $node['menu_name'];
		print '<br/>';
		if (isset($node['children']))
			display_tree($node['children'],$indent+1);
	}
}

// this two function is found from http://www.tommylacroix.com/2008/09/10/php-design-pattern-building-a-tree/

$mapped = array();
$mapped = mapTree($a);
display_tree($mapped);



Then it outputs only

Menu one
About
Weblink
Blog



Yes those are parent menu. But where is sub-menu?

Problem is in first function

i need to menu_id = menu_parent_id for submenu .... but how to use or set it

This post has been edited by hadi_php: 28 June 2010 - 03:17 AM

Was This Post Helpful? 0
  • +
  • -

#6 hadi_php  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 10
  • View blog
  • Posts: 382
  • Joined: 23-August 08

Re: Whats the best way to make multi-level dynamic menu?

Posted 28 June 2010 - 03:54 AM

Well this one work's for ME

function mapTree($dataset, $parent=0) {
	$tree = array();
	foreach ($dataset as $id=>$node) {
		if ($node['menu_parent_id'] != $parent) continue;
		$node['children'] = mapTree($dataset, $node['menu_id']);
		$tree[$id] = $node;
	}
	return $tree;
}


But new problem arrive

how i transformed it into

<ul>
    <li></li>
    <li>
         <ul>
              <li></li>
              <li></li>
         </ul>
    </li>
</ul>


Was This Post Helpful? 0
  • +
  • -

#7 hadi_php  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 10
  • View blog
  • Posts: 382
  • Joined: 23-August 08

Re: Whats the best way to make multi-level dynamic menu?

Posted 28 June 2010 - 05:07 AM

Ok Problem Sloved.... thanks Fratyr......it also helped me ..... a lot
Was This Post Helpful? 0
  • +
  • -

#8 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10390
  • View blog
  • Posts: 38,455
  • Joined: 27-December 08

Re: Whats the best way to make multi-level dynamic menu?

Posted 28 June 2010 - 03:12 PM

@Fratyr: Not really good practice to use 2D arrays to model Graphs or Trees. It is a sloppy and un-encapsulated approach to modeling these data structure, as evidenced by hadi_php's huge array (which is also a result of not using automation or querying). This is one more reason for OOP in this case, as you can utilize encapsulation.

@hadi_php: I'm glad you got it working, but I'd also like to suggest a more OO (and computer sciencey) alternative. I would start by designing a Node class with an array for child Nodes. Then, you just have to design a Tree class with basic methods for interacting with the structure you have set up, like adding data, removing data, getting/setting data, etc. In this way, the solution is way more modular, as you have a function as a solution which you don't have to recreate for future problems, and a Tree class which you don't have to recreate the functionality for each time when you need/want to use it. You can simply create an instance of the Tree class and use that.

Of course, I think we're still making things harder than they need to be. :) In my last post, I was pointing out the similarities between what you were trying to do and a Tree structure to get you thinking about how to solve the problem. You really could have kept the SQL table in tact, and just recursively queried.

As Trees are a type of Graph, you may want to check out my Graphs Tutorial. Although it is in Java, the concepts are the same and the syntax is close enough to PHP that you should be able to follow it. Also, you might find my tutorial on OOP and Encapsulation helpful as well.

This post has been edited by macosxnerd101: 28 June 2010 - 03:51 PM

Was This Post Helpful? 0
  • +
  • -

#9 Guest_hadi_php*


Reputation:

Re: Whats the best way to make multi-level dynamic menu?

Posted 07 July 2010 - 03:22 AM

well i am not familiar with class object .... [i use some ....collected...] . If you make TREE CLASS instead of this function

function mapTree($dataset, $parent=0) {
		$tree = array();
		foreach ($dataset as $id=>$node) {
			if ($node['parent_id'] != $parent) continue;
			$node['children'] = mapTree($dataset, $node['id']);
			$tree[$id] = $node;
		}
		return $tree;
	}



and i just able to display like this -

function displayAlbum($tree,$padding=0) {
		foreach($tree as $album_array) 
			{
				echo '<span style="padding-left:'.(5+$padding*10).'px" value="'.$album_array['album_id'].'">';
				echo $album_array['album_name'];
				echo '</span>';
					if(count($album_array['children'])>0)
						{
							displayAlbum($album_array['children'],$padding+1);
						}
				
			}
	}



Recursive method ... then i will use it and cheers! would you make this TREE CLASS for ARRAY?
Was This Post Helpful? 0

#10 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10390
  • View blog
  • Posts: 38,455
  • Joined: 27-December 08

Re: Whats the best way to make multi-level dynamic menu?

Posted 07 July 2010 - 06:45 PM

I think you misunderstand; a class isn't an array. A class is a blueprint or an abstract model for an Object. So basically with a Tree, we focus on the Nodes and how they are linked (a lot like a Linked List if you are familiar with such). So for example, this is how one would look (this is specifically a binary tree) like if you want a visual:
Posted Image

As you can see, we have a root node which connects to two Nodes (left and right). However, you can have n child Nodes the root connects to, as the picture above is a binary tree.

So we want to focus on two classes: a Node class and a Tree class. The Node class should probably focus on the following responsibilities:
  • Managing the value for the current Node
  • Managing connections to child nodes


The Tree class should handle the more advanced Node manipulation, though for your purposes, a simple insertion at the appropriate Child Node wll probably be sufficient. Like with a singly-Linked List, the Tree class should only store reference the Root Node, and access the Child Nodes from the Root. This means you will probably be using a lot of recursion. So to outline the responsibilities of the Tree class:
  • Store the root Node
  • Insert elements in their appropriate spots (probably as children nodes for the indices used for the query for the children)
  • Access elements (search)
  • Remove elements (good to have, but you probably won't need it)


Now that we've gone over the responsibilities of each class, I'll let you give it a try writing them. If you need a tutorial on Classes and Objects in PHP, check out my tutorial on classes and Objects in PHP.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1