1. PHP-Tipp: Dateipfad zu Array

    Stefan · 11.08.08, 20:20 Uhr · PHP, Programmierstil, Tutorials · Tags: , ,

    In einem Projekt benötigte ich aus diversen Gründen einen mehrdimensionalen Array aus einem Dateipfad. Aufgabenstellung ist recht klar und hört sich eigentlich einfach an, ist es aber leider nicht wirklich. Problem: der Pfad kann je nach Datei eine unterschiedliche Tiefe haben.

    Mein Ursprungsarray schaute wie folgt aus:

    $elements = array();
    $elements["dir1/dir2/dateiname.jpg"] = array("name" => "dateiname.jpg", "filesize" => "12345");
    $elements["dir1/dir2/dateiname2.jpg"] = array("name" => "dateiname2.jpg", "filesize" => "21534");
    $elements["dir2/dir1/dateiname1.jpg"] = array("name" => "dateiname1.jpg", "filesize" => "12345");
    $elements["dir2/dir1/dir1/dateiname1.jpg"] = array("name" => "dateiname1.jpg", "filesize" => "12345");
    $elements["dir2/dir2/dateiname1.jpg"] = array("name" => "dateiname1.jpg", "filesize" => "12345");

    Um daraus nun einen mehrdimensionalen Array zu erstellen gibt es verschiedene Möglichkeiten:

    1. Angenommen, alle Dateien liegen in gleichen Verzeichnistiefen, so kann man das über verschachtelte for/foreach-Schleifen fest reincodieren – beim obigen Beispiel funktioniert das leider nicht.
    2. Wir bauen uns eine rekursive Funktion die man jedes Mal mit dem erzeugten Ergebnis aufruft – das ist leider relativ langsam durch den function call
    3. Wir verwenden Schleifen mit referenzen auf den Urspungsarray

    Und genau den dritten Punkt habe ich folgendermaßen umgesetzt:

    $elementOrder = array();
    
    // durchlaufe alle array elemente
    foreach ( $elements as $path => $item ) {
    
        // teile den pfad in einzelne teile auf
        $pathParts = explode(DIRECTORY_SEPARATOR, $path);
        if ( !is_array($pathParts) || count($pathParts) < 1) {
            continue;
        }
    
        // erstelle die erste referenz auf unseren neuen array $elementOrder
        $e = &$elementOrder;
    
        // durchlaufe alle pfadteile in einer schleife ...
        for ( $i = 0; $i < count($pathParts) - 1; $i++) {
           if ( !isset($e[$pathParts[$i]]) ) {
               // ... und erzeuge ein neues array element falls noch nicht existent ...
               $e[$pathParts[$i]] = array();
           }
           // .. und weise hier unserer referenz eine neue array referenz zu ...
           $e = &$e[$pathParts[$i]];
        }
        // .. und füge hier das eigentliche datei item hinzu
        $e[] = $item;
    }

    Der Inhalt von $elementOrder schaut nach dieser Schleife wie folgt aus:

    Array
    (
        [dir1] => Array
            (
                [dir2] => Array
                    (
                        [0] => Array
                            (
                                [name] => dateiname.jpg
                                [filesize] => 12345
                            )
    
                        [1] => Array
                            (
                                [name] => dateiname2.jpg
                                [filesize] => 21534
                            )
    
                    )
    
            )
    
        [dir2] => Array
            (
                [dir1] => Array
                    (
                        [0] => Array
                            (
                                [name] => dateiname1.jpg
                                [filesize] => 12345
                            )
    
                        [dir1] => Array
                            (
                                [0] => Array
                                    (
                                        [name] => dateiname1.jpg
                                        [filesize] => 12345
                                    )
    
                            )
    
                    )
    
                [dir2] => Array
                    (
                        [0] => Array
                            (
                                [name] => dateiname1.jpg
                                [filesize] => 12345
                            )
    
                    )
    
            )
    
    )
  2. Kommentar schreiben

    XHTML: Du kannst diese Tags nutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Gehe zur polyCODER Startseite