Ankündigung

Einklappen
Keine Ankündigung bisher.

Problem bei Navigations-Funktion

Einklappen

Neue Werbung 2019

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

  • SilentSight
    hat ein Thema erstellt Problem bei Navigations-Funktion.

    Problem bei Navigations-Funktion

    Hi PHPler,

    ich habe mich mal an einer Klasse für mein Seitenlayout probiert und hänge an der Funktion, die eigentlich die Navigation aufbauen soll.
    Sie sieht folgendermaßen aus:

    PHP-Code:
      function writeNav($tid 1) {
        
    $active basename($_SERVER['PHP_SELF']);
        
        
    $nav_sel = new sqlQuery('SELECT * FROM navigation WHERE treeid="'.$tid.'" OR treeid IS NULL');
        echo 
    '<div id="navigation">';
          echo 
    '<div class="tree">';
          
    // Gibt alle Navigationsbäume aus
          
    while($nav $nav_sel->fetch()) {
            if(
    is_null($nav['treeid'])) {
              echo 
    '<h2>'.$nav['name'].'</h2>';
            }
            if(!
    is_null($nav['treeid'])) {
              
    // Gibt alle Eltern-Elemente aus
              
    if(is_null($nav['parentid'])) {
                echo 
    '<a href="'.$nav['url'].'" id="nav_'.(($active == $nav['url']) ? 'active' $nav['id']).'">'.$nav['name'].'</a>';
              } else {
                
    $parent_sel = new sqlQuery('SELECT url FROM navigation WHERE id="'.$nav['id'].'" LIMIT 1');
                
    $parent $parent_sel->fetch();
                
    // Gibt alle Kind-Elemente aus
                
    if($nav['url'] == $active || $parent['url'] == $nav['url']) {
                  echo 
    '<a href="'.$nav['url'].'" '.(($nav['url'] == $active) ? 'id="subnav_active"' '').' class="subnav">'.$nav['name'].'</a>';
                }
              }
            }
          }
        echo 
    '</div>';
        echo 
    '</div>';
      } 
    Meine Datenbankstruktur:
    Code:
    id | parentid | treeid | name | url
    wobei id automatisch vergeben wird, treeid die ID der Navigation ist. Also alles was unter treeid 1 stehen hat (Standard) gehört zur ersten Navigation. parentid ist die ID des übergeordneten Menüpunktes, name gibt den Text des Links an und url ist der Name der Datei (also z. B. impressum.php).

    Folgender Fehler tritt auf:
    Die Unterpunkte werden von allen Menüs angezeigt.

    Mein Ziel:
    Es sollen nur die Unterpunkte der ausgewählten Kategorie angezeigt werden und es soll auch in tiefere Ebenen funktionieren. Meins würde nämlich nur bis in die 2te Ebene funktionieren...

    Ich bin mir ziemlich sicher, dass mein ganzer Ansatz nicht wirklich richtig ist.

    Hoffe jemand von euch blickt da durch und kann mir weiterhelfen.

    SilentSight

  • SilentSight
    antwortet
    OK, habs verstanden...
    ich werde es wohl mit Nested-Sets machen =)

    Einen Kommentar schreiben:


  • Flor1an
    antwortet
    Bei Fakultäten kannst du das ganze auch nicht rekursiv lösen. Wobei keine der beiden Funktionen irgendwie schwer ist.
    PHP-Code:
    <?php
    // ohne Rekursion
    function fakultaet($i) {
        
    $result $i;
        for (
    $x $i-1$x 1$x--) {
            
    $result *= $x;
        }
        return 
    $result;
    }

    // mit rekursion
    function fakultaet($i) {
        if (
    $i <= 1) return 1;
        return 
    $i fakultaet($i-1);
    }

    Einen Kommentar schreiben:


  • litterauspirna
    antwortet
    Fakt ist aber eins,eine Rekursive Funktion nimmt die Performance mehr in Anspruch und kann die DB auch lahmlegen,was beim nested sets nicht passiert!

    Beispiel du hast eine Select Abfrage mit 6 Ebenen und nun hast du 300 User die in diesem Navigationsmenu zugreifen und sich wild durch klicken,dann kannst du dir ausrechnen wie viele querys da zustande kommen. Beim nested sets wird alles in einem query abgehandelt und somit ist die Performance nicht zum Zusammenbruch gefährdet!

    Aber wie gesagt ich tue mich auch bei beiden Sachen noch bisschen schwer. Ich weis zwar zum Beispiel wie man eine Fakultät einer Zahl berechnet aber das in Programmcode umzusetzen und die Abbruchbedingung zu schaffen,das macht mir auch Beschwerden!
    Und das nested sets ist wieder von SQL Statements her ziemlich kompliziert!

    Einen Kommentar schreiben:


  • Flor1an
    antwortet
    Naja das Argument mit Update und Insert zählt nicht wirklich.
    Die Navigation wird bei JEDEM Aufruf der Seite generiert (außer du erstellst einen Cache) und dadurch werden jedes mal 5 Querys erstellt. Angenommen du nimmst Nested Sets, hast du eben mehr Anfragen bei Update oder Insert. Aber wie oft findet den ein Update oder Insert statt? Im Normalfall nie. Ganz selten kommen mal Punkte hinzu! Und durch einmalige Handlungen geht die Performance nicht in die Knie. Denn die Navigation wird wohl nur der Admin ändern können, nicht aber jeder User. Daher musst du drauf achten WELCHE Operationen wirklich oft genutzt werden und genau diese dann Optimieren.

    Einen Kommentar schreiben:


  • SilentSight
    antwortet
    Aber diese Nested-Sets bringen doch eigentlich nur was, wenn ich ganz tiefe Ebenen habe?
    Ich glaube nicht, dass es so schlimm ist, wenn ich ein Menü mit 2-5 Ebenen habe und es mit einer rekursiven Funktion ausgeben muss.
    Das Nested-Sets-Modell hat auch seinen Nachteil:
    Das Updaten bzw. Inserten braucht halt mehrere Abfragen...

    Aber jetzt weiß ich wenigstens mal darüber Bescheid und werde mich mal mit beiden Methoden auseinandersetzen.

    Danke für die Hilfe
    SilentSight

    Einen Kommentar schreiben:


  • SilentSight
    antwortet
    Also, was eine rekursive Funktion ist, wusste ich schon
    Und mit dem SQL-Query hab ich auch den einen, der dann mindestens zu Anfang der Funktion aufgerufen wird.
    Dann werd ich wohl, um ein gutes DB-Design zu schaffen, nicht um die Nested-Sets rumkommen

    Danke für die Hilfe, ich meld mich dann nochmal, falls ich es so auch nicht schaffe.

    Bis denne, SilentSight

    Einen Kommentar schreiben:


  • litterauspirna
    antwortet
    Naja keinen extra Query in dem Sinne das du das jedes mal neu schreibst!

    Du musst eine Funktion schreiben die sich jedesmal wieder neu aufruft wenn sie verbindungen zu childs findet und ganz wichtig du musst eine abbruchbedingung schaffen sonst endet in einem endloslauf!

    Und ja eine Rekursive Lösung belastet bei großen Baumtiefen die Perfomance enorm,darum ist dafür die bessere aber auch nicht leicht zu verstehende Lösung nested sets!

    Einen Kommentar schreiben:


  • SilentSight
    antwortet
    Also muss ich bei der Rekursion für jede Ebene einen neuen SQL-Query erstellen?
    Das ist doch ziemlich belastend für die Datenbank oder nicht?

    Einen Kommentar schreiben:


  • litterauspirna
    antwortet
    Gib das mal in Google ein da findest einiges an guten Tuts.

    Naja es geht mit rekursion aber um eine Baumstrucktur oder so darzustellen kommst nicht drumherum oder aber nested sets,nur das habe ich bis jetzt auch nocht verstanden. Das Problem daran ist das es nicht so einfach ist wenn navigationspunkte verschieben willst oder löschen willst!

    Ein nested sets Modell sieht in der DB so aus!

    Code:
    id name lft rgt
    Da hast du praktisch den linken und rechten bezugspunkt eines childs mit abgespeichert. Die Performance wird in Mysql wird nicht so belastet weil alles in einer Abfrage gesteuert wird beim auslesen!

    Und bei der rekursion wird eine Funktion ja immer wieder ausgeführt wenn es sein soll und bei einer tieferen Struktur und wenn 200 User sich auf einmal durch deine Navigation klicken dann rappelts ganz schön in der DB!

    Hier mal ein TUT für nested sets [url=http://www.php-resource.de/tutorials/read/21/1/]Das 'Nested Sets' Modell - B

    Einen Kommentar schreiben:


  • SilentSight
    antwortet
    Rekursion find ich auch sehr schwierig zu verstehen, aber es ist wohl in diesem Thema die einzige bzw. beste Lösung!?

    Vom Nested-Sets-Modell habe ich noch nie etwas gehört, was ist das?

    Einen Kommentar schreiben:


  • litterauspirna
    antwortet
    Hallo!

    Ich habe es zwar nicht komplett Verstanden was du eigentlich willst,aber du könntest dir das Thema rekursion oder nested sets anschauen!

    Bei der rekursion habe ich auch ne ganze Weile gebraucht und habe noch Probleme das richtig umzusetzen und das nested sets modell ist sehr DB Performance freundlich weil alles in einer Abfrage passiert aber ich finde das auch relativ kompliziert!

    Einen Kommentar schreiben:


  • SilentSight
    antwortet
    Dann solltest du mal hier vorbeischauen:
    PHP: $_SERVER - Manual

    $_SERVER["SCRIPT_FILENAME"] gibt dir den absoluten Pfad deiner Datei.
    Dann kannst du den Pfad wie bei $_GET["cat"] benutzen!
    PHP-Code:
    $active basename($_SERVER['PHP_SELF']); 
    Ich brauch noch nen ID - ParentID Vergleich, welcher die Funktion in tiefere Ebenen hin nützlich macht.

    Beispiel:
    Code:
    id | parentid | treeid | name      | url
    1  | NULL     | 1      | Über mich | aboutme.php 
    2  | 1        | 1      | Beruf     | job.php
    3  | 2        | 1      | Anfang    | beginning.php
    Das meine ich mit tiefere Ebenen:
    Jetzt sind es drei Ebenen, weil Anfang nochmal unter Beruf steht.

    Kannst du mir nicht mal ein Beispiel geben, wie du es meinst?
    Oder kannst du mir vll. sagen, was ich in der Funktion, die ich zu Anfang gepostet hab falsch gemacht habe?

    Einen Kommentar schreiben:


  • dex
    antwortet
    Dann solltest du mal hier vorbeischauen:
    PHP: $_SERVER - Manual

    $_SERVER["SCRIPT_FILENAME"] gibt dir den absoluten Pfad deiner Datei.
    Dann kannst du den Pfad wie bei $_GET["cat"] benutzen!

    Einen Kommentar schreiben:


  • SilentSight
    antwortet
    Jo, ich weiß was du meinst. Aber so möchte ich es nicht lösen.
    Ich möchte nicht die Links als Query-String anhängen, sondern die Dateien als eigene aufrufen (also nicht index.php?cat=impressum sondern impressum.php).
    Sonst wäre es ja auch viel zu einfach

    Einen Kommentar schreiben:

Lädt...
X