PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr (https://www.php-resource.de/forum/)
-   PHP Developer Forum (https://www.php-resource.de/forum/php-developer-forum/)
-   -   Rekursive Navigation springt zurück (https://www.php-resource.de/forum/php-developer-forum/102796-rekursive-navigation-springt-zurueck.html)

Lehrling1991 24-03-2012 14:23

Rekursive Navigation springt zurück
 
Guten Morgen zusammen

Ich bin dabei eine Funktion zu programmieren, welche eine Navigation aus einem Verzeichnis erzeugt. Dieses wird mit dem Funktionsaufruf mitgegeben.
Wenn ich auf eine Ebene klicke übergebe ich mit GET den Pfad, worauf geklickt wurde.

Mein Problem ist: Sobald ich auf die 2 Ebene klicke, woraus die 3. Ebene aufgehen sollte, bin ich wieder auf der ersten. Der Pfad wird jedoch richtig übergeben.
Also z.B.
1. Ebene --> Verwaltung
2. Ebene --> Organigramme
3. Ebene --> Informatik

Also um nochmals zu erläutern: Wenn ich auf Verwaltung klicke gehen die Unterordner korrekt auf, jedoch wenn ich jetzt auf Organigramme klicke übergibt er mir zwar den Pfad korrekt, springt aber wieder zurück zur Ausgangsposition und schliesst alle Untermenüs.

Hier mal mein Code:

PHP-Code:

<?php 
function navigation_rekursiv($verzeichnis

    
$handle =  opendir($verzeichnis); 
    while (
$datei readdir($handle)) 
    { 
        if (
$datei != "." && $datei != ".."
        { 
            if (
is_dir($verzeichnis."/".$datei)) // Wenn Verzeichniseintrag ein Verzeichnis ist 
            

                echo 
"<a href=\"./Startseite.php?l=$verzeichnis$datei\">$datei</a><br>";
                
                if (isset(
$_GET['l'])) {
                    if (
$verzeichnis.$datei == $_GET['l']) {
                        
navigation_rekursiv($verzeichnis.$datei.'/');
                    }
                }
            }
            else
            { 
                
// Wenn Verzeichnis-Eintrag eine Datei ist, diese ausgeben
                
echo "<a href=\"./Startseite.php?l=$datei\">$datei</a><br>";
            }            
        }
    }
        
    
closedir($handle); 
}
navigation_rekursiv("./Inhalt/"); 
?>

Sieht jemand meinen Fehler??? Bin jetzt schon seit gestern dran und bekomms nicht raus..
Ich bin mir nicht sicher, aber müsste ich nicht die Funktion ein drittes mal aufrufen für die 3. Ebene? Nur wo?

MFG derLehrling

mermshaus 24-03-2012 15:53

Willkommen im Forum.

Das Problem lässt sich sicher auch so sehen, aber es würde dennoch immens helfen, wenn du deine Verzeichnisstruktur mit angeben könntest.

Die hast eben nur du vor dir.

Edit: Na gut, steht da im Grunde. Ich habe gepennt.

PHP-Code:

            if (isset($_GET['l'])) {
                if (
$verzeichnis.$datei === substr($_GET['l'], 0strlen($verzeichnis.$datei))) {
                    
navigation_rekursiv($verzeichnis.$datei.'/');
                }
            } 

Ist aber wohl mehr ein Hack.

Lehrling1991 24-03-2012 16:02

Dankeschön und auf eine gute Zeit :)

Also meine Ordnerstruktur hat maximum 3 Ebenen. Also spätenstens bei der 3. Ebene müssen es Files sein.
Der Gesamte Inhalt ist im Ordner Inhalt abgelegt.
Dieser hat folgenden Inhalt(was für ein wortspiel :D):

Allgemein
Abkuerzungen.pdf
Aufbewahrungfristen.pdf
Telefonlisten intern.pdf
Verwaltung
Abkuerzungen.pdf
Funktionendiagramme
Bauabteilung.pdf
Informatik.pdf
Verwaltung.pdf
Bauabteilung
File Upload
Informatik
Links


Also das ist jetzt nicht 100% identisch, das würde noch ein wenig dauern.. Aber wenn ich es richtig verstehe gehts einfach prinzipiell um den Aufbau?

Lehrling1991 24-03-2012 16:03

Zitat:

Zitat von mermshaus (Beitrag 660048)
Willkommen im Forum.

Das Problem lässt sich sicher auch so sehen, aber es würde dennoch immens helfen, wenn du deine Verzeichnisstruktur mit angeben könntest.

Die hast eben nur du vor dir.

Edit: Na gut, steht da im Grunde. Ich habe gepennt.


oh shit und ich hab das zu spät gesehen :D

mermshaus 24-03-2012 16:08

Ja, macht nichts. Ich habe deine Posts auch nicht gesehen. Schau dir aber noch mal meinen ersten Post an.

Lehrling1991 24-03-2012 16:25

Erstens: Vielen dank für deine Hilfe! Hat also das funktioniert.

Kannst du mir evtl noch erklären was du da genau machst?

Wenn ich es richtig verstehe: Du schneidest vom GET Parameter den letzten Teil ab, und Vergleichst ihn mit dem Wert der beim Funktionsaufruf übergeben wurde und dem neuen Handle?
Ist diese Bedingung erfüllt rufen wir die Funktion nun auf.

Lehrling1991 24-03-2012 16:26

ah und wieso hack?

Lehrling1991 24-03-2012 16:46

Gibt es jetzt eine Möglichkeit die verschiedenen Ebenen einzeln anzusprechen? Nicht oder?

Die 2. und 3. Ebene müsste man ja ein wenig einrücken, der Übersicht halber. Das ist so wie ich es jetzt habe nicht möglich oder?

mermshaus 24-03-2012 17:24

Mit Hack meine ich, dass die Lösung nicht besonders sauber und nicht vollständig durchdacht ist.

Ein Problem ist etwa, dass die Bedingung auch erfüllt ist, wenn der aktuelle Pfad „path“ lautet, und in $_GET['l'] etwa „patha“ steht. Das ist ein anderes Verzeichnis, erfüllt aber die Substring-Bedingung. Da müsste noch geprüft werden, ob das nächste Zeichen in $_GET['l'] ein Slash ist oder ob der String beendet ist.

So was „ordentlich“ zu schreiben, ist gar nicht so leicht.

PHP-Code:

function navigation_rekursiv($path$activePath$depth 0)
{
    
$path rtrim($path'/');

    
$ret = array();

    
$ret[] = array(
        
'depth' => $depth,
        
'path'  => $path,
        
'title' => basename($path)
    );

    if (
        
is_dir($path)
        && 
$path === substr($activePath0strlen($path))
        && 
in_array(substr($activePathstrlen($path), 1), array(false'/'))
    ) {
        
$handle opendir($path);

        while (
$datei readdir($handle)) {
            if (
$datei === '.' || $datei === '..') {
                continue;
            }

            
$ret array_merge(
                
$ret,
                
navigation_rekursiv($path '/' $datei$activePath$depth 1)
            );
        }

        
closedir($handle);
    }

    return 
$ret;
}

$rootPath './Inhalt';

if (!isset(
$_GET['l'])) {
    
$_GET['l'] = '';
}

$entries navigation_rekursiv($rootPath$_GET['l'], 0);

foreach (
$entries as $entry) {
    echo 
str_repeat('&nbsp;'$entry['depth'] * 4)
       . 
'<a href="./Startseite.php?l=' $entry['path'] . '">' $entry['title'] . '</a><br />';


Eigentlich müsste man eine Baumstruktur aufbauen.

Lehrling1991 24-03-2012 18:16

also erst mal wow! was du da aus meinem einfach code gemacht hast ist für mich wirklich erstaunlich..

Nun wärst du so gütig und würdest mir das erklären? Weil ich müsste ja noch selber anpassen.. :D

ich bin noch in der ausbildung, kann zwar schon einiges, aber das ist sehr hohes niveau und übersteigt meinen jetzigen horizont..!

mermshaus 24-03-2012 18:24

Was verstehst du denn konkret nicht?

Lehrling1991 24-03-2012 18:44

ok ich bin jetzt mal ein wenig schritt für schritt durchgegangen und langsam komm ich dahinter.

geh ich richtig in der annahme das du keinen unterschied in der behandlung von verzeichnisen und dateien machst?

mermshaus 24-03-2012 21:59

Ja, kann man so sagen. Das wird derzeit nur dort beachtet, wo es darum geht, zu entscheiden, ob Rekursion durchgeführt wird. Du könntest aber den Datensätzen in der Rückgabe (den einzelnen assoziativen Arrays) auch problemlos noch ein Feld 'is_file' => is_file($path) mitgeben und bei der Ausgabe entsprechend auslesen und je nach Wunsch eine andere Formatierung wählen.

Wesentlich bei meinem Ansatz ist die Trennung von der Ermittlung der Daten und der tatsächlichen Ausgabe (Kapselung, EVA-Prinzip). Bei mir ist klar definiert, welche Eingaben die Funktion erhält und welche Ausgabe sie liefert. Es gibt keine Seiteneffekte wie die Ausgabe innerhalb der Funktion und es wird auch nicht auf globale Variablen ($_GET) zugegriffen. Die Funktion kennt nur das, was ihr beim Aufruf übergeben wird. Das gestattet weitreichende und einfache Wiederverwendbarkeit des Codes, da er auch in Umgebungen einsetzbar ist, die nicht auf $_GET['l'] setzen und die nicht gleich an der Stelle des Aufrufs eine Ausgabe wünschen.

Dass ich den eigentlich Code zur Durchführung der Rekursion so umgeschrieben habe, dass jeder Aufruf definitiv ein Element („sich selbst“) zurückliefert, ist nicht zwangsläufig objektiv besser. Ich habe das gemacht, weil es erfahrungsgemäß gut ist, wenn Baumstrukturen ein einziges Wurzelelement haben.

Das muss jetzt keinen Sinn ergeben. Ich sage ja, es ist kompliziert, so was „ordentlich“ zu machen. Poste vielleicht später noch mehr dazu. Das deckt sich gerade mit etwas, das auch für mich interessant ist.

Lehrling1991 25-03-2012 15:20

Zitat:

Ja, kann man so sagen. Das wird derzeit nur dort beachtet, wo es darum geht, zu entscheiden, ob Rekursion durchgeführt wird. Du könntest aber den Datensätzen in der Rückgabe (den einzelnen assoziativen Arrays) auch problemlos noch ein Feld 'is_file' => is_file($path) mitgeben und bei der Ausgabe entsprechend auslesen und je nach Wunsch eine andere Formatierung wählen.
Also die Dateien werden ja mit Dateipfad übergeben, also kann ich das so in meinem Content-Bereich einfliessen lassen. Werd ich aber wenn ich ein wenig mehr Zeit habe probieren! Wär evtl. spannend um ein Datei/Ordnersymbol vor den Link zu setzten um ein wenig zu verdeutlichen was es ist..

Zitat:

Das muss jetzt keinen Sinn ergeben.
doche ergibt sinn! ist zwar nicht einfach zu verstehen, aber es geht immer besser!

also was ich jetzt gemacht habe: ich hab es so geändert das dass root verzeichnis nicht mehr ausgegeben wird. ob es elegant ist weiss ich nicht, das würd ich jetzt gerne von dir wissen :D
PHP-Code:

if (!isset($_GET['l'])) {
    
$_GET['l'] = './Inhalt/';
}

$entries navigation_rekursiv($rootPath$_GET['l'], 0);

foreach (
$entries as $entry) {
    if (
$entry['path'] != './Inhalt'){
    echo 
str_repeat('&nbsp;'$entry['depth'] * 4)
       . 
'<a href="./Startseite.php?l=' $entry['path'] . '">' $entry['title'] . '</a><br />';
    }


also ein paar fragen hab ich noch, wenn das ok für dich ist..
mir ist noch nicht ganz klar wie du auf die 3. ebene kommst. machst du das mit diesem Aufruf?
PHP-Code:

$ret array_merge(
                
$ret,
                
navigation_rekursiv($path '/' $datei$activePath$depth 1)
            ); 

bei der ersten if abfrage ist mir nicht klar wozu du die dritte bedingung hast? wieso braucht es die?

nun nur noch etwas: was ich gerade am probieren ist, lange dateinamen beim Zeilenumbruch auf gleicher Höhe zu halten. Hast du einen Tipp für mich?

Einen schönen Nachmittag :danke: & bis später!

Lehrling1991 11-04-2012 09:40

Hei Mermshaus

Möchte nur nochmal Zaghaft nachfragen :) Bin gerade verzweifelt am Probieren die Zeilenumbrüche auch einzurücken, aber bis jetzt kein Erfolg in Sicht..

Mfg Lehrling1991


Alle Zeitangaben in WEZ +2. Es ist jetzt 12:15 Uhr.

Powered by vBulletin® Version 3.8.2 (Deutsch)
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0
[c] ebiz-consult GmbH & Co. KG