Montag, 29. November 2010

Bühne frei für "glob"!

Nachdem wir ein paar gängigere Funktionen zum Durchlaufen eines Ordners betrachtet haben, soll eine weitere, etwas weniger bekannte Funktion vorgestellt werden:

Bühne frei für "glob"!

Die Funktion selbst ist recht einfach, bietet aber die Möglichkeit mit einfachen Suchmustern zu arbeiten. Sogar mehrere Ordner gleichzeitig lassen sich durchsuchen. Ähnlich wie bei "scandir" wird der Inhalt eines angegebenen Ordners als Array abgebildet welches direkt durchlaufen werden kann...
    foreach (glob($Ordner . '/*.txt') as $Datei){
        echo $Datei."\n";
    };
...oder zur weiteren Bearbeitung in einer Variablen gespeichert wird:
    $VerzeichnisArray = glob($Ordner . '/*.txt');

"glob" findet Dateien und Ordner, der durchsuchte Ordner "." wird nicht als Ergebnis angezeigt. Das Array ist sortiert, die einzelnen Ergebnisse beinhalten immer die gesamte Pfadangabe. Wer also nur den Dateinamen benötigt, muss diesen selbst abtrennen, beispielsweise mit basename($Datei,".txt"). Wer die Suche auf Ordner beschränken möchte, dem steht der Parameter GLOB_ONLYDIR zur Verfügung.

Kein Rennpferd

Messungen auf unterschiedlichen Systemen zeigen, dass "glob" unter vergleichbaren Bedingungen etwa 7 bis 20 mal so lange zur Ausführung benötigt wie die klassischen Funktionen "opendir" oder "scandir". Es spielt dabei keine Rolle ob das Ergebnis in einer Variablen zwischengespeichert oder mit dem optionalen Parameter GLOB_NOSORT auf eine Sortierung verzichtet wird - "glob" ist kein Rennpferd.

    $VerzeichnisArray = glob($Ordner . '/*.txt', GLOB_NOSORT);
    foreach ($VerzeichnisArray as $Datei){
        //leider auch nicht schneller
    };
"glob" ist damit nicht unbedingt empfehlenswert wenn hohe Performance benötigt wird, was aber kein Grund sein sollte grundsätzlich darauf zu verzichten - etwas Augenmaß ist immer gefragt.

The power of "glob"

Interessant wird "glob" durch seine Fähigkeit mit Wildcards zu arbeiten:

"MeinOrdner/*" findet im dem angegebenen Ordner alle Dateien und Ordner
"MeinOrdner/*.txt" findet alle Textdateien
"MeinOrdner/*Januar*.xml" findet alle XML-Dateien mit "Januar" im Namen.
Neben dem Stern "*" der beliebig viele Zeichen "frißt", gibt es noch "?" das für ein beliebiges Zeichen steht. Auch unter Windows unterscheidet "glob" zwischen Groß- und Kleinschreibung. Mit "*.txt" als Parameter wird "brief.Txt" beispielsweise nicht gefunden! Hier müssen mögliche Alternativen mit "[]" angegeben werden. Eine eckige Klammer steht für exakt eine Stelle und jedes in der Klammer angegebene Zeichen ist an dieser Stelle erlaubt.

glob("./*.[tT][xX][tT]");
*(Sicherlich gibt es eine Möglichkeit dies einfacher zu gestalten, leider konnte ich sie noch nicht finden.)

Selbst in die Pfadangabe können Wildcards gesetzt werden, so dass mit einer einfachen Abfrage mehrere Ordner auf einer Ebene gemeinsam durchsucht werden können. Einziger Nachteil: Der jeweilige Stammordner selbst wird so nicht berücksichtigt.

glob('MeinOrdner/*/*.[mM][pP]3');
Aber auch das geht, dazu müssen wir nur etwas tiefer in Trickkiste greifen.

Alternativen angeben

Mit dem Parameter GLOB_BRACE können in geschweiften Klammern verschiedene Alternativen angegeben werden, die nicht auf ein Zeichen beschränkt sind. Sie werden jeweils durch ein Komma getrennt.

glob('/{log,backup}*.txt', GLOB_BRACE)
So werden Dateien mit Namen wie "logfile.txt", "log10102010.txt", "backupfull.txt" gefunden.

Mit einem kleinen Trick können wir so auch einen Ordner inklusive seiner direkten Unterordnern durchsuchen, also eine Art rekursive Suche "light":

glob('/Musik/*{*,/}*.[mM][pP]3', GLOB_BRACE)
Auch nicht unbedingt schön, aber wirkungsvoll.

"... und du bist raus"

Zeichen können auch mit "!" negiert und von einer Suche ausgeschlossen werden. Im folgenden Beispiel werden alle Dateien gefunden, die nicht mit einer Zahl (0-9) beginnen.
glob($Ordner . '/Musik/[!0-9]*.*')

Viel Spaß mit GLOB!

Keine Kommentare:

Kommentar veröffentlichen