Mysql
 sql >> Datenbank >  >> RDS >> Mysql

So erstellen Sie eine unbegrenzte Menüebene über PHP und MySQL

Hier ist eine "entwicklerfreundliche" Version der "eine Abfrage , keine Rekursion " Lösung für dieses 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 .= '<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;

Sie müssen nur die Verwendung der Variable $parent_stack verstehen.

Es ist ein „LIFO“-Stapel (Last In, First Out) – das Bild im Wikipedia-Artikel sagt mehr als tausend Worte:http://en.wikipedia.org/wiki/LIFO_%28computing%29

Wenn eine Menüoption Unteroptionen hat, speichern wir ihre Eltern-ID im Stack:

array_push( $parent_stack, $parent );

Und dann aktualisieren wir sofort $parent und machen es zur aktuellen Menüoptions-ID:

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

Nachdem wir alle Unteroptionen durchlaufen haben, können wir zur vorherigen Ebene zurückkehren:

$parent = array_pop( $parent_stack );

Aus diesem Grund haben wir die Eltern-ID im Stack gespeichert!

Mein Vorschlag ist:Betrachten Sie das obige Code-Snippet und verstehen Sie es.

Fragen sind willkommen!

Einer der Vorteile, die ich in diesem Ansatz sehe, ist, dass er das Risiko eliminiert, in eine Endlosschleife zu geraten, was passieren kann, wenn Rekursion verwendet wird.