Wie man eine unbegrenzte Menüebene durch PHP und MySQL erstellt

8

Nun, um mein Menü zu erstellen, benutze ich eine db ähnliche Struktur wie diese

%Vor%

Um ein anderes Untermenü für ein bestehendes Untermenü zuzuweisen, gebe ich einfach die ID seines Elternteils als Wert des Elternfeldes ein. Eltern 0 bedeutet Top-Menü

jetzt gibt es kein Problem beim Erstellen eines Untermenüs in einem anderen Untermenü

Nun hole ich auf diese Weise das Untermenü für das oberste Menü

%Vor%

Was ich machen möchte ist.

Ich möchte prüfen, ob ein neues Menü ein anderes untergeordnetes Menü hat

und ich möchte weiter prüfen, bis es alle verfügbaren Kindermenüs durchsucht

und ich möchte sein untergeordnetes Menü in seinem bestimmten Listenelement wie diesem anzeigen

%Vor%     
Starx 20.05.2010, 07:48
quelle

8 Antworten

11

Sie müssen dafür rekursive Funktionen verwenden. Technisch gibt es ein paar Möglichkeiten, aber Rekursion ist hier wirklich die beste Option.

Hier ist der Grundgedanke, wie es funktionieren würde:

%Vor%

Die Eigenschaften und Methoden von $item sind nur Beispiele, und ich überlasse es Ihnen, diese zu implementieren, wie auch immer Sie es brauchen, aber ich denke, es vermittelt die Botschaft.

    
nickf 20.05.2010, 07:55
quelle
18

Hier ist eine "entwicklerfreundliche" Version der Lösung " eine Abfrage , keine Rekursion " für dieses Problem.

SQL :

%Vor%

PHP :

%Vor%

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

Es ist ein "LIFO" Stack (Last In, First Out) - das Bild im Wikipedia-Artikel sagt mehr als tausend Worte: Ссылка

Wenn eine Menüoption über Unteroptionen verfügt, speichern wir ihre übergeordnete ID im Stapel:

%Vor%

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

%Vor%

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

%Vor%

Deshalb haben wir die Eltern-ID im Stapel gespeichert!

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

Fragen sind willkommen!

Einer der Vorteile, den ich bei diesem Ansatz sehe, ist, dass das Risiko des Eintritts in eine Endlosschleife eliminiert wird, was bei der Rekursion auftreten kann.

    
J. Bruni 01.08.2010 00:32
quelle
16

Mit einer Datenbankstruktur wie der Ihren ist es möglich, das gesamte HTML-Menü mit einer einzelnen Abfrage und ohne Rekursion zu erstellen.

Ja - ich wiederhole:

  • EINE Frage
  • KEINE RECURSION

Dies ist der Ansatz, den ich immer selbst benutze.

Den Code hier eingefügt - voll funktionsfähig:

Ссылка

Springe zu Zeile 67, um den interessanten Teil ("get_menu_html") zu sehen.

Die Hauptschleife beginnt bei Zeile 85.

Es gibt fünf "anpassbare" HTML-Snippets:

  1. Menü-Wrapper öffnen (Zeile 83)
  2. menu wrapper closing (Zeile 122)
  3. Menüpunkt mit Childs-Eröffnung (Zeile 100)
  4. Menüeintrag mit schließenden Kindern (Zeile 92)
  5. Menüelement ohne Childs (Zeile 113)

(Der Code könnte sauberer sein, wenn ich mich nicht mit Tabellierung beschäftigt hätte.)

SQL zum Erstellen und Füllen der Beispieldatenbank ist am Ende des Skripts verfügbar.

Sie können versuchen, uns Ihre Gedanken mitzuteilen.

    
J. Bruni 30.07.2010 03:58
quelle
4

Ich würde vorschlagen, dass Sie in vorbestellte Baum Traversal schauen. Es gibt einen Artikel zu diesem Thema unter:

Hierarchische Daten in MySQL verwalten

Sie nehmen jede Seite effektiv als einen "Knoten". Jeder Knoten hat einen Verweis auf seine Eltern. Wenn Sie das Layout der Knoten ändern (ein untergeordnetes Element hinzufügen, Knoten verschieben usw.), berechnen Sie einen "linken" und "rechten" Wert für jeden Knoten neu (der Artikel oben erklärt dies sehr detailliert, mit Links zum Quellcode in PHP) ). Was Sie am Ende haben, ist die Fähigkeit, sehr schnell zu bestimmen, ob ein bestimmter Knoten ein direkter oder indirekter Nachfolger eines anderen Knotens ist, sowie alle untergeordneten Knoten eines bestimmten Knotens zu erhalten.

    
Kazar 20.05.2010 07:56
quelle
1

Ссылка

Sie müssen Rekursion verwenden, aber meine Herangehensweise ist anders, ich habe eine Klasse erstellt, um jedes Menü einzeln zu behandeln, dann nach Ergebnissen gefragt und alle Elemente in ihrem individuellen Objekt nach ihren Eltern gruppiert, geordnet nach Ebenen und dann zusammengeführt alle Objekte in einem ... überprüfen Sie die Pastebin für den vollständigen Code

    
Carlos Arturo Alaniz 19.06.2013 20:30
quelle
0

Ich würde eine rekursive Funktion verwenden.

Ich weiß, das ist nicht genau wie Ihr Code, aber ich denke, Sie können das allgemeine Konzept erhalten, wenn Sie Rekursion verstehen. Wenn Sie die Rekursion nicht verstehen, sehen Sie sich Ссылка

an %Vor%     
jordanstephens 20.05.2010 07:56
quelle
0

Ich habe diesen Weg gefunden und arbeite mit Yii Framework.

%Vor%

Für den Fall, dass Sie eine weitere Ebene benötigen, können Sie eine weitere Ebene im Child-Array wie hijos_de_hijos erstellen und den Vergleich dann in der if-Anweisung durchführen.

Natürlich, um zu vergleichen, ob cn_id_menu_padre leer ist, sollte der Wert in der Datenbank null sein.

    
Jose Rivas 10.06.2016 09:22
quelle

Tags und Links