Rekursive Funktion und Speichern im assoziativen Array
Greener
- php
Hallo Forumfreunde, ich habe gerade ein bisschen mit PHP zu kämpfen und vielleicht könnt ihr mir ja helfen.
Ich habe ein Verzeichnis und in diesem Verzeichnis wieder Unterverzeichnise mit Dateien also eine komplexe Verzeichnisstruktur mit unendlich vielen möglichen Ebenen.
Der Hintergrund ist, dass ich diese Verzeichnisstruktur nachher auf der Website als Menü ausgeben möchte. Jeder Ordner ist dann ein Menüpunkt, jeder Unterordner ein weiterer Menüpunkt und jede Datei auch ein Menüpunkt.
Dabei habe ich nun folgende Probleme: wie speichere ich die Verzeichnisstruktur und wie kann ich im assoziativen Array speichern, ob eine Datei oder ein Verzeichnis vorliegt.
Nachher sollte das ganze so aussehen:
Array:
ordner1
ordner2
ordner3
textdatei1
textdatei2
textdatei3
ordner4
textdatei4
ordner5
ordner6
textdatei5
textdatei6
Diese Funktion hier habe ich mir schon gebastelt:
[code lang=php]
function auflisten($eintrag)
{
if (is_dir($eintrag))
{
echo $eintrag."/<br>";
$verzeichnis = scandir($eintrag);
foreach ($verzeichnis as $neuer_eintrag)
{
if ($neuer_eintrag == "." || $neuer_eintrag == "..")
continue;
auflisten($eintrag."/".$neuer_eintrag);
}
}
else
{
echo $eintrag."<br>";
}
}
[/php]
Sie gibt unformatiert mit Rekursion das ganze aus. Aber wie speicher ich das nun in einem Array ab anstatt es auszugeben?
Vielen dank für eure gute Hilfe!
echo $begrüßung;
[...] wie kann ich im assoziativen Array speichern, ob eine Datei oder ein Verzeichnis vorliegt.
Eine Datei ist ein String, ein Verzeichnis ein Array. is_array() und !is_array() können zum Unterscheiden herangezogen werden.
echo "$verabschiedung $name";
echo $begrüßung;
[...] wie kann ich im assoziativen Array speichern, ob eine Datei oder ein Verzeichnis vorliegt.
Eine Datei ist ein String, ein Verzeichnis ein Array. is_array() und !is_array() können zum Unterscheiden herangezogen werden.
Naja, aber wie baue ich denn nun in die Funktion ein, dass das ganze in einem Array (sagen wir mal $struktur) gespeichert werden sollte?
Eigentlich müsste ich ja dafür einen weiteren Parameter erstellen, in dem gespeichert ist, an welcher Stelle im Array ich mich gerade befinde, damit ich an dieser Stelle abspeichern kann. Aber wie kann ich dynamisch auf die Xte Ebene eines Arrays zugreifen?
Hi,
Eigentlich müsste ich ja dafür einen weiteren Parameter erstellen, in dem gespeichert ist, an welcher Stelle im Array ich mich gerade befinde, damit ich an dieser Stelle abspeichern kann. Aber wie kann ich dynamisch auf die Xte Ebene eines Arrays zugreifen?
Die x-te Ebene hat dich bei einem *rekursiven* Vorgehen doch gar nicht zu kuemmern - sondern immer nur die *aktuelle*.
Wenn ein Verzeichnis vorliegt, dann lege es als Array-Element an, und weise ihm die Rueckgabe des (rekursiven) Funktionsaufrufes zu.
Pseudocode:
function lese_verzeichnis(...) {
$array = array();
while(Eintrag = readdir()) {
if(Eintrag == Verzeichnis) {
$array[] = lese_verzeichnis(Eintrag);
}
else {
$array[] = Eintrag;
}
return $array;
}
MfG ChrisB
Hello,
Pseudocode:
function lese_verzeichnis(...) {
$array = array();
while(Eintrag = readdir()) { ## an die Datei namens '0' denken, also auf === false prüfen
if(Eintrag == Verzeichnis) { ## versuche mal is_dir auf einem Linux-System, wenn es ein
## Link eist auf ein Directory
$array[] = lese_verzeichnis(Eintrag);
}
else {
$array[] = Eintrag;
}
return $array;
}
Dieses Beispiel kann durchaus ein Problem mit einer Endlosschliefe durch zirkulären Verlauf bekommen, wenn nämlich ein Link auf ein höheres Verzeichnis vorhanden ist.
Ein harzliches Glückauf
Tom vom Berg
![](http://selfhtml.bitworks.de/Virencheck.gif)
--
Nur selber lernen macht schlau
<http://bergpost.annerschbarrich.de>
Hi,
Eigentlich müsste ich ja dafür einen weiteren Parameter erstellen, in dem gespeichert ist, an welcher Stelle im Array ich mich gerade befinde, damit ich an dieser Stelle abspeichern kann. Aber wie kann ich dynamisch auf die Xte Ebene eines Arrays zugreifen?
Die x-te Ebene hat dich bei einem *rekursiven* Vorgehen doch gar nicht zu kuemmern - sondern immer nur die *aktuelle*.
Pseudocode:
function lese_verzeichnis(...) {
$array = array();
while(Eintrag = readdir()) {
if(Eintrag == Verzeichnis) {
$array[] = lese_verzeichnis(Eintrag);
}
else {
$array[] = Eintrag;
}
return $array;
}
Danke, irgendwie hatte ich eine Blockade. Das mit dem "file === 0" ist übrigens kein Problem, weil ich diese Verzeichnisbäume manuell erstelle und eine Datei mit 0 nicht vorkommen wird.
Noch eine letzte Frage: könnten Probleme auftreten, wenn ich folgendes mache?:
Pseudocode:
~~~php
function lese_verzeichnis(...) {
$array = array();
while(Eintrag = readdir()) {
if(Eintrag == Verzeichnis) {
$array[Eintrag] = lese_verzeichnis(Eintrag); # Index enthält nun Name des Verzeichnis
}
else {
$array[Eintrag] = 123; # Index enthält nun Name der Datei, der Inhalt (123) ist bedeutungslos
}
return $array;
}
Das muss ich machen, damit mir nicht die Namen des Ordners verloren gehen, weil ein Ordner ja in diesem Falle ein Array ist und der Index nach ChrisBs Methode nur eine Zahl ist.
Hi,
Das mit dem "file === 0" ist übrigens kein Problem, weil ich diese Verzeichnisbäume manuell erstelle und eine Datei mit 0 nicht vorkommen wird.
Aber . und .. kommen vor - und da haben wir schon das von Tom angesprochene Problem, wenn auch leicht anders, als er meinte.
Noch eine letzte Frage: könnten Probleme auftreten, wenn ich folgendes mache?:
$array[Eintrag] = lese_verzeichnis(Eintrag); # Index enthält nun Name des Verzeichnis
}
else {
$array[Eintrag] = 123; # Index enthält nun Name der Datei, der Inhalt (123) ist bedeutungslos
Sollte eigentlich keine Probleme geben.
Ein Datei-/Verzeichnisname ist ja pro Ebene eindeutig, und was assoziative Array-Indices angeht, ist PHP nicht sonderlich pingelig.
MfG ChrisB