Verzeichnisse und Unterverzeichnisse auslesen
maddi
- php
0 Vinzenz Mai0 salt0 Tom
Hi alle zusammen,
ich möchte gern alle verzeichnisse und unterverzeichnisse auslesen und bin echt irgendwie grad zu doof ;o)
Ich habe das Verzeichnis Verz.
in Verz gibt es UV1, UV2, UV3, etc.
in UV1 gibt es UUV1, UUV2 und in UV3 gibt es UUV1, UUV2 und so weiter...
Ich möchte gern ein array dass alle verzeichnisse ab Verz. mit / getrennt enthällt, also der form:
Array[0]= Verz
Array[1]= Verz/UV1
Array[2]= Verz/UV1/UUV1
Array[3]= Verz/UV1/UUV2
Array[4]= Verz/UV2
Array[5]= Verz/UV3
Array[6]= Verz/UV3/UUV1
Array[6]= Verz/UV3/UUV2
Sorry, hab die Foreneinträge bereits durchsucht und bin ned wirklich weiter... :o(
Wäre spitze, wenn mir jemand mal nen ordentlichen Tritt gibt, damit ich von der Leitung rutsch... ;o)
Vielen Dank und Grüße,
matze
Hallo
ich möchte gern alle verzeichnisse und unterverzeichnisse auslesen und bin echt irgendwie grad zu doof ;o)
[...]
Sorry, hab die Foreneinträge bereits durchsucht und bin ned wirklich weiter... :o(
wie wäre es mit diesem Archivposting von Felix Riesterer?
Freundliche Grüße
Vinzenz
Hello,
ich möchte gern alle verzeichnisse und unterverzeichnisse auslesen und bin echt irgendwie grad zu doof ;o)
wie wäre es mit diesem Archivposting von Felix Riesterer?
Das würde ich unkommentiert nicht empfehlen:
$pfad = preg_replace('~(.*)/$~', '\1', $pfad); // letzten Slash aus dem String entfernen
## das geht mit rtrim($pad,'/') sparsamer.
$liste = array();
$lesezugriff = opendir($pfad);
while($ein_eintrag = readdir($lesezugriff))
## das ist bekanntermaßen falsch, weil dann bei einer Datei oder einem Verzeichnis mit
## dem Namen '0' Schluss wäre mit der Schleife.
while(($ein_eintrag = readdir($lesezugriff)) !== false)
## wäre daher besser. Steht aber inzwischen auch schon länger auch in der PHP-Doku
Außerdem bin ich gerade unsicher, ob dieses Verfahren nicht auch zu einer Endlos-Schleife führen könnte. Wenn man einen Link auf ein übergeordnetes Verzeichnis erwischt, könnte es zu einem zyklischen Verlauf kommen. Ich habe es noch nicht ausprobiert (kommt auf den Zettel).
Ich würde daher aus dem Bauch raus nur echte Verzeichnisse (also nicht Link und nicht . oder ..) weiter auflösen.
Für die ganze Aufgabe bietet sich auch glob() an
http://de3.php.net/manual/en/function.glob.php,
das die gewünschte Expansion des Pfades vom Startpunkt aus schon selber vornimmt.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hello,
zumindest für das Zusammensammeln der Verzeichnisse unter Vermneidung eines zyklischen Verlaufes (hoffe ich jedenfalls) habe ich eine Lösung gebastelt.
Ich habe mich bemüht, das globale Scope nicht zu beschmutzen.
Dies ist übrigens ein Anwendungsfall für das gute alte Pärchen list() + each()
Das Ergebnis der Liste braucht man dann nur noch einmal durchzuarbeiten, um zu den Verzeichnissen auch die Dateien zu finden.
<?php ### glob_all_dirs.php ###
#---------------------------------------------------------
function append_dirs(&$_list,$start_folder)
{
## Directory-Liste des Unterverzeichnisses bschaffen
$_entries = glob($start_folder.'/*', GLOB_ONLYDIR);
## beschaffte Liste abarbeiten und übergeben
foreach ($_entries as $key => $symbolic)
{
## Symbolische und relative Angaben auflösen
$realpath = realpath($symbolic);
## Hinten anhängen an Sammelliste, wenn noch nicht
## darin enthalten
if (!in_array($realpath, $_list))
{
$_list[] = $realpath;
}
}
}
#---------------------------------------------------------
function get_subdirs($start_folder)
{
$_list = array();
$_list[] = $start_folder;
while (list($key, $dir) = each($_list))
{
append_dirs($_list, rtrim($dir,'/'));
}
natsort($_list);
return $_list;
}
#---------------------------------------------------------
$start_folder = "/home/thomas/web/php4";
echo "<pre>\n";
echo htmlspecialchars(print_r(get_subdirs($start_folder),1));
echo "</pre>\n";
?>
Ihr könnt die Lösung ja mal (zer-)diskutieren ;-)
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hello,
kleiner Nachtrag.
Zum Sortieren eignet sich natcasesort() mMn etwas besser, als natsort().
Aber sonst gefällt es mir selber ganz gut. :-)
Habe die Lösung bisher jedenfalls nicht zum Aufhängen treiben können...
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
echo $begrüßung;
Ich hab nur Kleinigkeiten.
function get_subdirs($start_folder)
{
$_list = array();
$_list[] = $start_folder;while (list($key, $dir) = each($_list))
{
append_dirs($_list, rtrim($dir,'/'));
}
Es ist bei der Lösung unbedingt darauf zu achten, dass während der Laufzeit der while-Schleife das Array in $_list nicht einer anderen Variable zugeordnet wird, sonst wird der Array-Zeiger wieder auf Anfang gestellt und man erhält eine Endlos-Schleife. Da du hier $_list als Referenz an append_dirs() übergibst tritt dieser Fall nicht ein.
Ist die Aufteilung in zwei Funktionen hier wirklich sinnvoll? Kann man append_dirs() auch allein für eine sinnvolle Aufgabe verwenden?
$_entries = glob($start_folder.'/*', GLOB_ONLYDIR);
foreach ($_entries as $key => $symbolic)
Du verwendest $_entries für nichts weiter als einen Zwischenspeicher. Wirst du nach der Anzahl der Zeilen bezahlt? :-) Die Zeile wird auch nicht dramatisch länger, wenn das glob gleich im foreach steht. Dann bleibt nur das foreach übrig, und das pass auch noch in die while-Schleife.
Außerdem hast du zweimal eine Variable $key notiert, die du nicht verwendest, weder im foreach noch beim list. So geht es auch:
foreach (glob(...) as $symbolic)
while (list(, $dir) = each($_list))
echo "$verabschiedung $name";
Hello,
Ist die Aufteilung in zwei Funktionen hier wirklich sinnvoll? Kann man append_dirs() auch allein für eine sinnvolle Aufgabe verwenden?
Ob man es sinnvoll nutzen kann, weiß ich nicht.
Aber nutzen kann man es einzeln.
Hatte ich mir auch überlegt, ob beide Teile zusammen in eine einzige Funktion packen sollte...
$_entries = glob($start_folder.'/*', GLOB_ONLYDIR);
foreach ($_entries as $key => $symbolic)
wird zu:
foreach (glob(...) as $symbolic)
while (list(, $dir) = each($_list))
Ok, das ist kompakter.
Ich hatte es nur ausfühlich geschreiben, damit man noch leicht nachvollziehen kann, was passiert.
Und das "lose Komma" beim list() macht mich immer nervös.
Ob man das rtim(...,'/') auch wirklich braucht, habe ich auch noch überlegt.
Ich gehe davon aus, dass es auch eine Sequenz '////' vom Ende entfernen würde?
Das habe ich noch nie ausprobiert. Da aber realpath() auch npch tätig wird, könnte man es sich sicherlich schenken, wenn man beide Teile in eine Funktion packt.
Man kann auch paranoid werden beim Programmieren.
Eine gewisse Zuverlässigkeit sollte man seinen Programmen und Funktionen doch schon zutrauen, aber das Thema, wo man da die Grenze ziehen muss, hatten wir neulich schon.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
echo $begrüßung;
Ob man das rtim(...,'/') auch wirklich braucht, habe ich auch noch überlegt.
Da fällt mir ein, dafür gibt es doch eine Konstante DIRECTORY_SEPARATOR, die je nach System mit / oder \ belegt ist. Allerdings tendiere ich dazu, die nur schreibend zu verwenden und in dem Fall ein hart kodiertes '/' dem rtrim() zu übergeben.
Ich gehe davon aus, dass es auch eine Sequenz '////' vom Ende entfernen würde?
Ja, das ist seine Aufgabe.
echo "$verabschiedung $name";
echo $begrüßung;
Außerdem bin ich gerade unsicher, ob dieses Verfahren nicht auch zu einer Endlos-Schleife führen könnte. Wenn man einen Link auf ein übergeordnetes Verzeichnis erwischt, könnte es zu einem zyklischen Verlauf kommen. Ich habe es noch nicht ausprobiert (kommt auf den Zettel).
Ich würde daher aus dem Bauch raus nur echte Verzeichnisse (also nicht Link und nicht . oder ..) weiter auflösen.
Beachte dann auch SymLinks. Die verweisen gern mal auf . besonders wenn irgendwelche historischen Verzeichnisstrukturen weiter unterstützt werden müssen, sich aber mittlerweile die Struktur geändert hat.
echo "$verabschiedung $name";
Hi,
ich würde wohl die Struktur generell erstmal so:
Array[0] = Verz; // verz
Array[0][0] = UV1; // verz/uv1
Array[0][0][0] = UUV1; // verz/uv1/uuv1
Array[0][0][1] = UUV2; // verz/uv1/uuv2
Array[0][1] = UV2; // verz/uv2
Array[0][2] = UV3; // verz/uv3
Array[0][2][0] = UUV1; // verz/uv3/uuv1
Array[0][2][1] = UUV2; // verz/uv3/uuv2
abbilden, dann kann man sich gescheiter in dem array bewegen.
Ggf. kann man die erste Ebene auch weglassen, wobei da aber lieber der root-path reinsollte.
Hello,
ich würde wohl die Struktur generell erstmal so:
Array[0] = Verz; // verz
Array[0][0] = UV1; // verz/uv1
Array[0][0][0] = UUV1; // verz/uv1/uuv1
Array[0][0][1] = UUV2; // verz/uv1/uuv2
Array[0][1] = UV2; // verz/uv2
Array[0][2] = UV3; // verz/uv3
Array[0][2][0] = UUV1; // verz/uv3/uuv1
Array[0][2][1] = UUV2; // verz/uv3/uuv2abbilden, dann kann man sich gescheiter in dem array bewegen.
Unabhängig davon, dass ich den Nutzen nicht erkennen kann,
eie soll das gehen?
Wenn Array[0] mit einem String belegt ist, kann Array[0][0] gar nicht angelegt werden und Array[0][0][0] natürlich auch nicht.
Die Arrayelemente in PHP können immer nur _entweder_ einen Datenwert (Skalar, Logsicher Wert) aufnehmen _oder_ einen Verweis auf eine weitere Liste. Daraus entsteht dann eine Baumstruktur.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom