SHARE
TWEET

How to build unlimited levels menu through PHP and MySQL

a guest Jul 29th, 2010 13,585 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2.  
  3. /**
  4.  * Generate HTML for multi-dimensional menu from MySQL database
  5.  * with ONE QUERY and WITHOUT RECURSION
  6.  * @author J. Bruni
  7.  */
  8. class MenuBuilder
  9. {
  10.         /**
  11.          * MySQL connection
  12.          */
  13.         var $conn;
  14.        
  15.         /**
  16.          * Menu items
  17.          */
  18.         var $items = array();
  19.        
  20.         /**
  21.          * HTML contents
  22.          */
  23.         var $html  = array();
  24.        
  25.         /**
  26.          * Create MySQL connection
  27.          */
  28.         function MenuBuilder()
  29.         {
  30.                 $this->conn = mysql_connect( 'localhost', 'user', 'pass' );
  31.                 mysql_select_db( 'example', $this->conn );
  32.         }
  33.        
  34.         /**
  35.          * Perform MySQL query and return all results
  36.          */
  37.         function fetch_assoc_all( $sql )
  38.         {
  39.                 $result = mysql_query( $sql, $this->conn );
  40.                
  41.                 if ( !$result )
  42.                         return false;
  43.                
  44.                 $assoc_all = array();
  45.                
  46.                 while( $fetch = mysql_fetch_assoc( $result ) )
  47.                         $assoc_all[] = $fetch;
  48.                
  49.                 mysql_free_result( $result );
  50.                
  51.                 return $assoc_all;
  52.         }
  53.        
  54.         /**
  55.          * Get all menu items from database
  56.          */
  57.         function get_menu_items()
  58.         {
  59.                 // Change the field names and the table name in the query below to match tour needs
  60.                 $sql = 'SELECT id, parent_id, title, link, position FROM menu_item ORDER BY parent_id, position;';
  61.                 return $this->fetch_assoc_all( $sql );
  62.         }
  63.        
  64.         /**
  65.          * Build the HTML for the menu
  66.          */
  67.         function get_menu_html( $root_id = 0 )
  68.         {
  69.                 $this->html  = array();
  70.                 $this->items = $this->get_menu_items();
  71.                
  72.                 foreach ( $this->items as $item )
  73.                         $children[$item['parent_id']][] = $item;
  74.                
  75.                 // loop will be false if the root has no children (i.e., an empty menu!)
  76.                 $loop = !empty( $children[$root_id] );
  77.                
  78.                 // initializing $parent as the root
  79.                 $parent = $root_id;
  80.                 $parent_stack = array();
  81.                
  82.                 // HTML wrapper for the menu (open)
  83.                 $this->html[] = '<ul>';
  84.                
  85.                 while ( $loop && ( ( $option = each( $children[$parent] ) ) || ( $parent > $root_id ) ) )
  86.                 {
  87.                         if ( $option === false )
  88.                         {
  89.                                 $parent = array_pop( $parent_stack );
  90.                                
  91.                                 // HTML for menu item containing childrens (close)
  92.                                 $this->html[] = str_repeat( "\t", ( count( $parent_stack ) + 1 ) * 2 ) . '</ul>';
  93.                                 $this->html[] = str_repeat( "\t", ( count( $parent_stack ) + 1 ) * 2 - 1 ) . '</li>';
  94.                         }
  95.                         elseif ( !empty( $children[$option['value']['id']] ) )
  96.                         {
  97.                                 $tab = str_repeat( "\t", ( count( $parent_stack ) + 1 ) * 2 - 1 );
  98.                                
  99.                                 // HTML for menu item containing childrens (open)
  100.                                 $this->html[] = sprintf(
  101.                                         '%1$s<li><a href="%2$s">%3$s</a>',
  102.                                         $tab,   // %1$s = tabulation
  103.                                         $option['value']['link'],   // %2$s = link (URL)
  104.                                         $option['value']['title']   // %3$s = title
  105.                                 );
  106.                                 $this->html[] = $tab . "\t" . '<ul class="submenu">';
  107.                                
  108.                                 array_push( $parent_stack, $option['value']['parent_id'] );
  109.                                 $parent = $option['value']['id'];
  110.                         }
  111.                         else
  112.                                 // HTML for menu item with no children (aka "leaf")
  113.                                 $this->html[] = sprintf(
  114.                                         '%1$s<li><a href="%2$s">%3$s</a></li>',
  115.                                         str_repeat( "\t", ( count( $parent_stack ) + 1 ) * 2 - 1 ),   // %1$s = tabulation
  116.                                         $option['value']['link'],   // %2$s = link (URL)
  117.                                         $option['value']['title']   // %3$s = title
  118.                                 );
  119.                 }
  120.                
  121.                 // HTML wrapper for the menu (close)
  122.                 $this->html[] = '</ul>';
  123.                
  124.                 return implode( "\r\n", $this->html );
  125.         }
  126. }
  127.  
  128. $menu = new MenuBuilder();
  129. echo '<pre>' . htmlentities( $menu->get_menu_html() ) . '</pŕe>';
  130.  
  131. /*** SAMPLE DATABASE: ***
  132.  
  133. CREATE TABLE `menu_item` (
  134.   `id` int(11) NOT NULL,
  135.   `title` varchar(75) DEFAULT NULL,
  136.   `link` varchar(100) DEFAULT NULL,
  137.   `parent_id` int(11) DEFAULT NULL,
  138.   `position` int(11) DEFAULT NULL,
  139.   PRIMARY KEY (`id`)
  140. );
  141.  
  142. INSERT INTO `menu_item` (`id`, `title`, `link`, `parent_id`, `position`) VALUES (1,'1','1.html',0,1);
  143. INSERT INTO `menu_item` (`id`, `title`, `link`, `parent_id`, `position`) VALUES (2,'2','2.html',0,2);
  144. INSERT INTO `menu_item` (`id`, `title`, `link`, `parent_id`, `position`) VALUES (3,'11','11.html',1,1);
  145. INSERT INTO `menu_item` (`id`, `title`, `link`, `parent_id`, `position`) VALUES (4,'12','12.html',1,2);
  146. INSERT INTO `menu_item` (`id`, `title`, `link`, `parent_id`, `position`) VALUES (5,'21','21.html',2,1);
  147. INSERT INTO `menu_item` (`id`, `title`, `link`, `parent_id`, `position`) VALUES (6,'22','22.html',2,2);
  148. INSERT INTO `menu_item` (`id`, `title`, `link`, `parent_id`, `position`) VALUES (7,'3','3.html',0,3);
  149.  
  150. */
  151.  
  152. ?>
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top