Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment créer un niveau illimité de menu via PHP et mysql

Voici une version "conviviale pour les développeurs" de "une requête , pas de récursivité " solution à ce problème.

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 .= '<li>' . $option['value']['title'] . '</li>';
            $html .= '<ul>'; 
            array_push( $parent_stack, $parent );
            $parent = $option['value']['id'];
        }
        // 2) The item does not contain children
        else
            $html .= '<li>' . $option['value']['title'] . '</li>';
    }
    // 3) Current parent has no more children:
    // jump back to the previous menu level
    else
    {
        $html .= '</ul>';
        $parent = array_pop( $parent_stack );
    }
}

// At this point, the HTML is already built
echo $html;

Vous avez juste besoin de comprendre l'utilisation de la variable $parent_stack.

C'est une pile "LIFO" (Last In, First Out) - l'image dans l'article de Wikipedia vaut mille mots :http://en.wikipedia.org/wiki/LIFO_%28informatique%29

Lorsqu'une option de menu a des sous-options, nous stockons son ID parent dans la pile :

array_push( $parent_stack, $parent );

Et puis, nous mettons immédiatement à jour $parent, ce qui en fait l'ID d'option de menu actuel :

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

Après avoir bouclé toutes ses sous-options, nous pouvons revenir au niveau précédent :

$parent = array_pop( $parent_stack );

C'est pourquoi nous avons stocké l'ID parent dans la pile !

Ma suggestion est la suivante :considérez l'extrait de code ci-dessus et comprenez-le.

Vos questions sont les bienvenues !

L'un des avantages que je vois dans cette approche est qu'elle élimine le risque d'entrer dans une boucle infinie, ce qui peut se produire lorsque la récursivité est utilisée.