Ankündigung

Einklappen
Keine Ankündigung bisher.

Baumstruktur anzeigen

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Baumstruktur anzeigen

    Hallo,

    ich bin am verzweifeln !

    Und zwar möchte ich eine Baumstruktur eines Menus anzeigen.

    In etwa so:
    - Root
    |
    |-Oberpunkt 1
    | |
    | |- Unterpunkt 1.1
    | | |
    | | |- Unterpunkt 1.1.1
    | |
    | |- Unterpunkt 1.2
    |
    |- Oberpunkt 2
    |
    Es soll alles aus der Datenbank gelesen werden.
    Die Datenbank schaut wie folgt aus:


    id | pid | MenuName |
    ---------------------------------
    1 | 0 | Oberpunkt 1
    ---------------------------------
    2 | 0 | Oberpunkt 2
    ---------------------------------
    3 | 1 | Unterpunkt 1.1
    ---------------------------------
    4 | 3 | Unterpunkt 1.1.1
    ---------------------------------
    5 | 1 | Unterpunkt 1.2
    ---------------------------------
    Also wie gesagt will ich das ganze Menu anzeigen lassen. Wie eine Sitemap oder so.

    Ich komme jetzt nur so weit das ich folgendes Anzeigen kann:

    - Root
    |
    |-Oberpunkt 1
    | |
    | |- Unterpunkt 1.1
    | | |
    | | |- Unterpunkt 1.1.1
    | |
    Und zwar mit foldendem Code:
    Code:
    <?PHP
    
    function showmenu($pid=0) {
    global $db, $_GET;
    $dbg = $db->Select();
    $row = $db->SelectPuffer;
    if($db->Rows) {
      for($i=0; $i<$db->Rows; $i++) {
       $newID = $row[$i][uid];
       echo $row[$i][MenuName]."
    ";
       $next = content::showmenu($newID);
    }
    }
    ?>
    Ich weiß das das irgendwie Rekursiv zu machen ist. Mir fehlt noch der entscheidene Hinweis was ich noch übergeben muß.
    Wie lese ich jetzt das komplette Menu aus? Kann mir da jemand helfen. Hab eine Hirnblockade.

    Vielen Dank im Vorraus.

  • #2
    Niemand weiss, was $db soll bzw. ist, niemand weiss, was in $dbg steht und niemand weiss, was in $row steht. Vielleicht löst sich die Hirnbolckade durch ein paar var_dumps, wenn nicht hilft die vielleicht uns.

    Und btw. eine bessere Antwort kriegt man im Fortgeschrittenen-Forum nicht, ausser: Irgendwie sieht deine Datenbank-Schnittstelle leicht merkwürdig aus.
    [url]www.php-maven.org[/url] PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks
    Twitter @ [url]https://twitter.com/#!/mepeisen[/url] und Facebook @ [url]http://t.co/DZnKSUih[/url]

    Kommentar


    • #3
      Also $db ist die Datenbank Abfrage eine Klasse die Abfragen macht.
      $row ist das Ergebnis der Abfrage und $dbg ist nur für das Debugging da.

      Kommentar


      • #4
        Die Datenbanktabelle stellt nur einen Ausschnitt dar.

        Mir gehts nicht darum ob ich die Abfrage falsch mache sondern wie ich die Rekursion so hinbekomme das ich alle Punkte im Menu anzeige.

        Kommentar


        • #5
          Vielleicht sollte man hierfür wissen, was in den Variablen drinsteht, um dir diesbezüglich Tips zu geben. Auf den ersten Blick ruft die Methode sich selber auf (das wäre die Rekursion), aber die übergebene ID ($pid) wird nie verwendet... Etwas merkwürdig...
          [url]www.php-maven.org[/url] PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks
          Twitter @ [url]https://twitter.com/#!/mepeisen[/url] und Facebook @ [url]http://t.co/DZnKSUih[/url]

          Kommentar


          • #6
            hi, du fragst die datenbank rekursiv ab, und das ist nicht nur unschön, mit steigender anzahl der menüpunkte kannst du damit die komplette anwendung zum erliegen bringen u.O. den datenbank-server zum absturz bringen. du brauchst nämlich mindestens genau so viele datenbankabfragen wie du menüpunkte hast. bei 50 menüpunkten sind das schon 50 queries.

            "global $_GET" ist übrigens unsinn, $_GET ist eh überall verfügbar. kannst dir die alte angewohnheit von $HTTP_GET_VARS gleich abgewöhnen.

            es gibt für baumstrukturen in datenbanken z.b. das "nested sets" modell (google fragen, nicht mich), aber das ist nichts für anfänger oder fortgeschrittene. weitaus günstiger und einfacher wäre es (für dich), wenn du das menü mit ID und inhalt in einem xml-dokument speicherst. dann sind zwar die daten an zwei stellen, aber es ist bei weitem einfacher handzuhaben.

            //my 2 c
            axo

            Kommentar


            • #7
              PHP-Code:
              <?php

              function showmenu($pid=0) { 
               
              $query mysql_query("SELECT id, pid, MenuName FROM menu WHERE pid = ".$pid.""DB); 
              $row mysql_fetch_array($query);
              $num mysql_num_rows($query);
              if(
              $num) { 
                for(
              $i=0$i<$num$i++) { 
                 
              $newID $row[$i][id]; 
                 echo 
              $row[$i][MenuName]."
              "

                 
              $next content::showmenu($newID); 




              ?>
              Vielleicht ist es so verständlicher?

              Kommentar


              • #8
                Zitat von axo
                "global $_GET" ist übrigens unsinn, $_GET ist eh überall verfügbar. kannst dir die alte angewohnheit von $HTTP_GET_VARS gleich abgewöhnen.
                Und wenn die function eine Methode ist dann auch? Ist dann Get auch überall verfügbar?

                Ich habe REGISTER_GLOBALS = off?

                Kommentar


                • #9
                  $_GET ist überall verfügbar. immer, auch bei Methoden.

                  Das obige sieht schon richtiger aus ($pid wird verwendet), auch wenn ich axo zustimmen würde, dass man das anders lösen sollte. Siehe google.
                  [url]www.php-maven.org[/url] PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks
                  Twitter @ [url]https://twitter.com/#!/mepeisen[/url] und Facebook @ [url]http://t.co/DZnKSUih[/url]

                  Kommentar


                  • #10
                    OK. Verstanden.
                    Frage mich nur warum Typo3 dann nicht nach dem Nested Set arbeitet?
                    Oder meint ihr das gerade deswegen Typo3 in der Performance langsam ist?

                    Würde mich mal interessieren.

                    Gruß

                    Kommentar


                    • #11
                      Zitat von alter mann
                      OK. Verstanden.
                      Frage mich nur warum Typo3 dann nicht nach dem Nested Set arbeitet?
                      Oder meint ihr das gerade deswegen Typo3 in der Performance langsam ist?

                      Würde mich mal interessieren.

                      Gruß
                      zu dem zeitpunkt, an dem kasper mit typo3 angefangen hat, gab es das modell glaub ich noch gar nicht , und ich trau mich wetten (beim anschauen des codes), dass er (zumindest damals) auch als datenbank-programmierer nicht erfahren genug war.

                      er hat sich aber auf andere weise beholfen: er hat einen mächtigen und relativ gut durchdachten caching-mechanismus gebaut, der diese 'design-schwächen' ausgleicht. außerdem braucht typo3 - soweit ich das sehe, nur eine abfrage pro menüebene, und da die meisten menüs nur ca. 3-5 ebenen tief sind, braucht er für's menü auch nur max. 5 abfragen.

                      mit dem nested set model braucht man aber nur fix 2 abfragen, egal wie tief das ganze geht. kleiner unterschied

                      Kommentar


                      • #12
                        Hi "alter mann".

                        Aus deinem Beispiel-Baum wird nicht ersichtlich, ob tatsächlich der komplette Baum angezeigt werden soll oder nur die übliche Navigationsansicht, in der quasi alle Knoten "collapsed" sind, die nicht auf dem Pfad zum aktuellen Knoten liegen.

                        Nested Sets eignen sich prima für Lesezugriffe, da sich viele übliche Anfragen in eine Query packen lassen. Allerdings sind Schreibzugriffe ziemlich teuer, da bei einer einfachen Änderung der ganze Rest des Baumes geändert weden muss. Also für Sitemaps prima geeignet, für Foren absolut nicht.

                        Hier ein ganz gutes Tutorial:
                        http://develnet.org/36.html

                        Basti

                        Kommentar


                        • #13
                          Hi Basti,

                          es soll der komplette Baum angezeigt werden, weil es kein Menu werden soll sondern eine Übersicht.

                          Dachte ich mir das Nested Set ein Manko hat. Wenn man nämlich einen Punkt verschiebt dann muß man alle Punkte die darunter liegen abändern. Viel zu kompliziert finde ich.

                          Vielleicht kannst du mir bei dem Problem helfen?

                          Wie gesagt will ich den kompletten Baum anzeigen lassen und komme bis jetzt nur wie bei 1 beschrieben.

                          :P

                          Kommentar


                          • #14
                            Hi.

                            Ich kopier dir hier mal eine Sitemap-Klasse von mir rein, ist aber sicher schnell an deine
                            Anforderungen angepasst. Im Konstruktor liest du einfach die komplatte DB-Tabelle ein und die
                            Aufrufe an das Sitemap-Objekt kannst du ja leicht anpassen. Vielleicht geschickt erstmal alle
                            Datensätze durchzugehen und den Root-Knoten extra zu speichern, sowie ein Array mit allen
                            Knoten die Kinder haben. Etwa so:
                            PHP-Code:
                            <?php
                            while ($r->fetch() = $aRecord) {
                                if (
                            $aRecord['parent'] === 0) {
                                    
                            $this->iRootNode $aRecord-['parent'];
                                } else {
                                    
                            $this->aChildren[$aRecord][] = $aRecord;
                                }
                            }
                            ?>
                            Ach ja, die Klasse:
                            PHP-Code:
                            <?php

                            class SitemapMenu
                            {
                                private 
                            $Sitemap null;
                                
                                public function 
                            __construct(Sitemap $Sitemap)
                                {
                                    
                            $this->Sitemap $Sitemap;
                                }
                                
                                public function 
                            render($sPre ''$sIndent="\t"$aSubTree null)
                                {
                                    if (!isset(
                            $aSubTree))
                                        
                            $aSubTree = array($this->Sitemap->getRootNode());

                                    if (
                            === sizeof($aSubTree))
                                        return 
                            '';
                                    
                                    
                            $sHTML "$sPre<ul>\n";
                                    
                                    foreach (
                            $aSubTree as $aItem) {
                                        
                            $sHTML .= "$sPre$sIndent[*]";
                                        
                            $sHTML .= sprintf(
                                            
                            '[url="%s"]%s[/url]',
                                            
                            $aItem['url'],
                                            
                            $aItem['title']);
                                        
                                        if (
                            $this->Sitemap->hasChildren($aItem['id'])) {
                                        
                                            
                            $sHTML .= "\n";
                                            
                            $sHTML .= $this->render(
                                                
                            $sPre.$sIndent.$sIndent
                                                
                            $sIndent,
                                                
                            $this->Sitemap->getChildNodes($aItem['id']));
                                            
                            $sHTML .= "$sPre$sIndent";
                                        }    
                                            
                                        
                            $sHTML .= "\n";
                                    }
                                    
                            $sHTML .= "$sPre[/list]\n";
                                    
                                    return 
                            $sHTML;
                                }
                            }
                            ?>
                            Basti

                            Kommentar

                            Lädt...
                            X