PHP Database driven Multilevel Menu

2019-07-08 09:35发布

问题:

I want to built a database driven multilevel menu I got it from [http://abhijitpal.in/][1] but the problem here is i can't put class = "dropdown" only to the top menus <ul>, it also get applies to the sub menus as well. I just modified a little but I don't know how to use recursive function. Below is the code, please see if you can help

<?php     /** Function to display Catelogue Menu */

//select all rows from the main_menu table
$q ="SELECT * FROM catelogue WHERE cat_visibility = '1'";    
$r = mysqli_query($dbc, $q);

//create a multidimensional array to hold a list of menu and parent menu
$menu = array(
    'menus' => array(),
    'parent_menus' => array()
);

//build the array lists with data from the menu table
while ($row = mysqli_fetch_assoc($r)) {
    //creates entry into menus array with current menu id ie. $menus['menus'][1]
    $menu['menus'][$row['cat_id']] = $row;
    //creates entry into parent_menus array. parent_menus array contains a list of all menus with children
    $menu['parent_menus'][$row['cat_parentid']][] = $row['cat_id'];
}

    // Create the main function to build milti-level menu. It is a recursive function.  
    function nav_catelogue($parent, $menu) {
    //$html = "";
    if (isset($menu['parent_menus'][$parent])) { ?>
<ul>
        <?php
        foreach ($menu['parent_menus'][$parent] as $menu_id) {
            if (!isset($menu['parent_menus'][$menu_id])) { ?>
                <li><a href="<?php echo $menu['menus'][$menu_id]['link']; ?>"><?php echo $menu['menus'][$menu_id]['cat_name']; ?></a></li>
  <?php }
            if (isset($menu['parent_menus'][$menu_id])) { ?>
        <li><a href="#"><?php echo $menu['menus'][$menu_id]['cat_name']; ?></a>
                        <?php echo nav_catelogue($menu_id, $menu); ?>
                    </li>
            <?php }
        } ?>
     </ul>
<?php }

} 
?>

My Database structure is

-----------------------------------------
| cat_id   | cat_name    | cat_parentid |
-----------------------------------------
|  1       |  Home       |  0           |
|  2       |  About      |  0           |
|  3       |  Contact    |  0           |
|  4       |  History    |  2           |
|  5       |  Services   |  2           |
-----------------------------------------

Desired Output I want:

  • HOME
  • ABOUT
    • History
    • Services
  • Contact

This is the final code as per @Mave

<?php     /** Function to display Catelogue Menu */

//select all rows from the main_menu table
$q ="SELECT * FROM catelogue WHERE cat_visibility = '1'";    
$r = mysqli_query($dbc, $q);

//create a multidimensional array to hold a list of menu and parent menu
$menu = array(
    'menus' => array(),
    'parent_menus' => array()
);

//build the array lists with data from the menu table
while ($row = mysqli_fetch_assoc($r)) {
    //creates entry into menus array with current menu id ie. $menus['menus'][1]
    $menu['menus'][$row['cat_id']] = $row;
    //creates entry into parent_menus array. parent_menus array contains a list of all menus with children
    $menu['parent_menus'][$row['cat_parentid']][] = $row['cat_id'];
}

    // Create the main function to build milti-level menu. It is a recursive function.  
    function nav_catelogue($parent, $menu, $top = false) {
        if (isset($menu['parent_menus'][$parent])) {
            //this is short code for if($top === true) { //do true } else { //do false }
            echo $top ? '<ul class="dropdown">' : '<ul>';
            foreach ($menu['parent_menus'][$parent] as $menu_id) {
                if (!isset($menu['parent_menus'][$menu_id])) {
                    echo '<li><a href="' . $menu['menus'][$menu_id]['link'] . '">' . $menu['menus'][$menu_id]['cat_name'] . '</a></li>';
                }
                if (isset($menu['parent_menus'][$menu_id])) {
                    echo '<li><a href="#">' . $menu['menus'][$menu_id]['cat_name'] . '</a>' . nav_catelogue($menu_id, $menu) . '</li>';
                }
            }
            echo '</ul>';
        }
    }
?>

回答1:

function nav_catelogue($parent, $menu, $top = false) {
    if (isset($menu['parent_menus'][$parent])) {
        //this is short code for if($top === true) { //do true } else { //do false }
        echo $top ? '<ul class="dropdown">' : '<ul>';
        foreach ($menu['parent_menus'][$parent] as $menu_id) {
            if (!isset($menu['parent_menus'][$menu_id])) {
                echo '<li><a href="' . $menu['menus'][$menu_id]['link'] . '">' . $menu['menus'][$menu_id]['cat_name'] . '</a></li>';
            }
            if (isset($menu['parent_menus'][$menu_id])) {
                echo '<li><a href="#">' . $menu['menus'][$menu_id]['cat_name'] . '</a>' . nav_catelogue($menu_id, $menu) . '</li>';
            }
        }
        echo '</ul>';
    }
}

When you first call nav_catelogue (not present in your current code), call it with nav_catelogue($menu_id, $menu, true);



回答2:

You have two ways to make your recursive function put the

class="dropdown"

The first way is to go for a calling/callee style in which your calling function will treat the first case(class="dropdown") and then call the recursive function which will handle the general case(no class="dropdown").

Add an argument(boolean ?) that you'll transmit at first call and which will add the class="dropdown". On the recursive calls you'll transmit this boolean as false(no class="dropdown" insertion).



标签: php mysql menu