How to build unlimited level of menu through PHP and mysql

前端 未结 8 1464
心在旅途
心在旅途 2020-11-29 01:05

Well, to build my menu my menu I use a db similar structure like this

  2  Services                  0
  3  Photo Gallery             0
  4  Home                         


        
8条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-29 01:31

    Here is a "developer-friendly" version of the "one query, no recursion" solution for this problem.

    SQL:

    SELECT id, parent_id, title, link, position FROM menu_item ORDER BY parent_id, position;
    

    PHP:

    $html = '';
    $parent = 0;
    $parent_stack = array();
    
    // $items contains the results of the SQL query
    $children = array();
    foreach ( $items as $item )
        $children[$item['parent_id']][] = $item;
    
    while ( ( $option = each( $children[$parent] ) ) || ( $parent > 0 ) )
    {
        if ( !empty( $option ) )
        {
            // 1) The item contains children:
            // store current parent in the stack, and update current parent
            if ( !empty( $children[$option['value']['id']] ) )
            {
                $html .= '
  • ' . $option['value']['title'] . '
  • '; $html .= '
      '; array_push( $parent_stack, $parent ); $parent = $option['value']['id']; } // 2) The item does not contain children else $html .= '
    • ' . $option['value']['title'] . '
    • '; } // 3) Current parent has no more children: // jump back to the previous menu level else { $html .= '
    '; $parent = array_pop( $parent_stack ); } } // At this point, the HTML is already built echo $html;

    You just need to understand the usage of the $parent_stack variable.

    It is a "LIFO" stack (Last In, First Out) - the image in the Wikipedia article worths a thousand words: http://en.wikipedia.org/wiki/LIFO_%28computing%29

    When a menu option has sub-options, we store its parent ID in the stack:

    array_push( $parent_stack, $parent );
    

    And then, we immediately update $parent, making it be the current menu option ID:

    $parent = $option['value']['id'];
    

    After we looped all its sub-options, we can return back to the previous level:

    $parent = array_pop( $parent_stack );
    

    This is why we stored the parent ID in the stack!

    My suggestion is: contemplate the code snippet above, and understand it.

    Questions are welcome!

    One of the advantages I see in this approach is that it eliminates the risk of entering into an infinite loop, which can happen when recursion is used.

提交回复
热议问题