• Rekursives Erstellen von Verzeichnissen

    Rekursives Erstellen von Verzeichnissen

    Inhalt

    1. Unser Problem
    2. Der Ansatz
    3. Die Planungsphase
    4. Wir bauen die Funktion

    Vorwort

    Was lerne ich hier?

    Hier lernst, du wie du mit Hilfe der Rekursion eine verbesserte mkdir()-Funktion erstellst.

    Wie benutze ich dieses Tutorial?

    In diesem Tutorial wird dir wahrscheinlich viel Unbekanntes begegnen. Solltest du einen Beispielcode nicht verstehen, gib nicht gleich auf. Meist habe ich bei etwas komplizierten Funktionen oder Konstrukten vorher eine entsprechende Info mit einem weiterführendem Link eingefügt. Es lohnt sich, diese Links im Zweifelsfall zu verfolgen.
    Die folgenden Symbole werden dir im Tutorial öfters begegnen:
    • Hinter diesem Symbol verbergen sich wichtige Infos
    • Hier findest du weiterführende oder zusätzliche Informationen zum aktuellen Kapitel
    • Sollte dir ein Konstrukt oder eine Funktion unbekannt erscheinen, oder solltest du Probleme bekommen, halte nach diesem Symbol Ausschau.

    Bevor du dieses Tutorial beginnst, solltest du wissen, was Rekursion bedeutet und du solltest in der Lage sein, sie anzuwenden. Dazu empfehle ich dieses Tutorial.


    1. Unser Problem Wenn du schonmal mit der Funktion mkdir() gearbeitet hast, wirst du vielleicht schon mal folgende Fehlermeldung gesehen haben:
    Warning: mkdir() [function.mkdir]: Datei oder Verzeichnis nicht gefunden in /opt/lampp/htdocs/Test3.php on line 14
    Wenn du noch nie mit der Funktion mkdir() gearbeitet hast, oder sie nur sporadisch kennst, kannst du sie hier nachschlagen. Leider ist die deutsche Version noch nicht aktualisiert, also musst du wohl oder übel mit der englischen Vorlieb nehmen.

    In dem beschriebenen Fall habe ich mkdir() folgendermaßen aufgerufen:
    PHP-Code:
    mkdir("/opt/lampp/htdocs/project/gallery_2/thumbs"); 
    Hmm.... die Syntax stimmt, was ist also schiefgegangen?

    Ich habe versucht, in einem meiner Projektordner einen Gallerieordner und darin einen Ordner für die Thumnails zu erstellen.

    Allerdings kann mkdir() bei so einem Aufruf nur einen Ordner erstellen, wenn der Rest der Verzeichnisstruktur bereits besteht.
    Also müsste der Ordner
    Code:
    /opt/lampp/htdocs/project/gallery_2
    bereits bestehen, damit ich darin den Ordner thumbs erstellen kann.

    Diesem Problem kann man nun in zwei Versionen entgegen wirken.
    Wenn man bereits für PHP 5 entwickeln kann man die Besonderheit von mkdir() nutzen, Verzeichnisse rekursiv zu erstellen (s. Manual).

    Oder wir basteln uns die entsprechende Funktion selber. Immerhin haben wir ja bereits das Handwerkszeug gelernt. Und außerdem kann man nicht immer davon aus gehen, dass unsere Skripts auf einem Server mit PHP 5 laufen.

    Dann wollen wir mal anfangen.


    2. Der Ansatz

    Zuerst sollten wir uns den Ansatz überlegen.
    Können wir überhaupt unser Problem rekursiv lösen?

    Ich habe folgenden Ansatz gefunden:


    Wir überprüfen zuerst, ob das zu erstellende Verzeichnis schon existiert. (Das ist unsere Abbruchbedingung. Wenn ja, machen wir nichts).
    Wenn es noch nicht existiert, prüfen wir, ob das übergeordnete Verzeichnis existiert. Wenn ja, erstellen wir das Verzeichnis, dass uns übergeben wurde und sind fertig.
    Wenn das übergeordnete Verzeichnis nicht existiert, überprüfen wir, ob das darüber existiert, und immer so weiter, bis endlich ein Verzeichnis existiert, was spätestens bei / so sein wird.

    Was heißt das nun konkret an unserem Beispiel?
    uns wird folgendes Verzeichnis übergeben
    Code:
    /opt/lampp/htdocs/project/gallery_2/thumbs
    und wir können annehmen, dass
    Code:
    /opt/lampp/htdocs/project
    existiert.

    Nun überprüfen wir, ob
    Code:
    /opt/lampp/htdocs/project/gallery_2
    existiert.

    Das ist nicht der Fall, also prüfen wir, ob
    Code:
    /opt/lampp/htdocs/project
    existiert.


    Dies existiert und darum können wir
    Code:
    /opt/lampp/htdocs/project/gallery_2
    per mkdir() erstellen.


    Nun können wir auch
    Code:
    /opt/lampp/htdocs/project/gallery_2/thumbs
    erstellen und wir sind fertig.


    Unser Problem,
    Code:
    /opt/lampp/htdocs/project/gallery_2/thumbs
    zu erstellen, ist also eher das Problem, zuerst
    Code:
    /opt/lampp/htdocs/project/gallery_2
    und danach
    Code:
    /opt/lampp/htdocs/project/gallery_2/thumbs
    zu erstellen.


    Und das Problem
    Code:
    /opt/lampp/htdocs/project/gallery_2
    zu erstellen, können wir ebenfalls in das Problem, zuerst
    Code:
    /opt/lampp/htdocs/project
    und dann
    Code:
    /opt/lampp/htdocs/project/gallery_2
    zu erstellen umwandeln.


    Das Problem
    Code:
    /opt/lampp/htdocs/project
    zu erstellen, ist dagegen nicht mehr umwandelbar, da das Verzeichnis bereits existiert.


    3. Die Planungsphase

    Überlegen wir uns mal ein paar Punkte:
    1. Unser Problem, das wir rekursiv aufrufen, ist, nacheinander zuerst den übergeordnete Ordner zu erstellen und danach den eigentlichen Ordner.
    2. Was ich übergeben können muss, ist eindeutig der zu erstellenden Ordner als String.
    3. Wir wollen zuerst überprüfen, ob der übergebene Ordner bereits existiert. Existiert er bereits, wollen wir keinen weiteren rekursiven Aufruf.
    4. Existiert der Ordner bereits soll nichts geschehen. Es ist keine Aktion notwendig.
    5. Wenn er noch nicht existiert, soll die Funktion rekursiv mit dem übergeordneten Ordner aufgerufen werden. Wir brauchen also den übergeordneten Ordner als String.
    6. Die einzelnen Probleme lösen sich dadurch, dass sie ggf. ihren übergebenen Ordner erstellen. Dadurch vereinen sich alle Lösungen zur Lösung des Originalproblems. Eine besondere Aktion (Summe, etc.) ist nicht nötig. Daher muss auch nichts zurückgegeben werden.
    7. Da wir keine "negativen" Pfadangaben angeben können und jede Ordnerstruktur erfolgreich auf / reduzieren können, müssen wir nicht mit einer Endlosschleife rechnen.



    4. Wir bauen die Funktion

    Nachdem wir uns also diese Gedanken gemacht haben, können wir loslegen.
    Unsere Funktion braucht zuerst einmal einen Namen.
    PHP-Code:
    function mkdir_rek($dir) {

    $dir stellt den Ordner als String da, der erstellt werden soll.


    Sollte dir so ein Konstrukt unbekannt erscheinen, lies dir bitte das hier durch, bevor du fortfährst!


    Nun fügen wir unsere Abbruchbedingung und unseren nicht-rekursiven Weg ein.
    Unsere Abbruchbedingung ist, dass der Ordner bereits existiert. Da in diesem Fall keine Aktion statt findet, ist auch nichts zu sehen, als die if-Abfrage.
    PHP-Code:
    functio mkdir_rek($dir) {
      if (!
    is_dir($dir) {
      }

    So nun ist es an der Reihe, unseren rekursiven Weg zu programmieren.
    Wir benötigen ja den übergeordneten Ordner. Dabei hilft uns die Funktion dirname(). Sie ermöglicht es uns aus /opt/lampp/htdocs/project/gallery_2/thumbs/opt/lampp/htdocs/project/gallery_2 zu machen. Also den übergeordneten Ordner.

    Den wollen wir dann durch die Funktion schicken und danach /opt/lampp/htdocs/project/gallery_2/thumbs per mkdir() erstellen.

    Das ganze sieht dann so aus:
    PHP-Code:
    function mkdir_rek($dir) {
        if (!
    is_dir($dir)) {
            
    mkdir_rek(dirname($dir));
            
    mkdir($dir);
        }

    Und das wars schon. Unsere rekursive Funktion zum erstellen von Ordnern ist einsatzfähig. Du kannst sie ja mal testen.

    Damit die Funktion richtig arbeiten kann ist es natürlich wichtig, dass das PHP-Script überhaupt Schreibrechte im existierenden Ordner hat.

    Ich habe dir hier die Funktion als php-Script angehängt.
    Nur habe ich sie dahingehend verbessert, als dass man nun auch die Maskierung der neu erstellten Ordner angeben kann.
    Ursprünglich wurde dieser Artikel in diesem Thema veröffentlicht: [PHP] Rekursives Erstellen von Verzeichnissen - Erstellt von: Jojo Original-Beitrag anzeigen

    Impressum · Tutorials · Nutzungsbedingungen · thematisch sortierte Linklisten · Spendenaufruf · Team · Partnerprojekte

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48