| Verzeichnisse vergleichen, Dateileichen finden |
Verzeichnisse vergleichen, Dateileichen findenGelegentlich kommt es vor, dass man zwei Verzeichnisse vergleichen möchte um festzustellen, ob sich darin identische Dateien befinden. Ein klassischer Fall wäre hier z.B. eine Galerie, die Thumbnails in einem Verzeichnis liegen hat und die zugehörigen Bilder in hoher Auflösung in einem anderen Verzeichnis. Oftmals speichert man in einer Datenbank nur den Name des Bildes und sucht sich die Bilder aus den Verzeichnissen zusammen. Löscht man jetzt ein Bild, oder lädt ein Bild über ein Webinterface auf den Server, und es kommt während dieser Operation zu einem Problem, kann es vorkommen, dass man nur das Image oder nur das Thumbnail auf dem Server hat. Ohne passendes Gegenstück handelt es sich hier um eine Dateileiche. Jetzt gibt es verschiedene Möglichkeiten die Verzeichnisse für Thumbs und Images zu vergleichen. Am häufigsten trifft man wohl diese, dass aus einem Verzeichnis alle Dateien ermittelt werden und dann in einer Schleife Datei für Datei mit file_exists im anderen Verzeichnis das Gegenstück gesucht wird. Das muss man dann in beide Richtungen machen, da ja entweder Thumb oder Image fehlen kann. Stattdessen möchte ich hier eine sehr schlichte Variante vorstellen, die zum einen schnell ist, ohne Schleife auskommt und im Prinzip gerade mal aus 3 PHP-Funktionen besteht! Ordner images:
Array
(
[0] => echse.jpg
[1] => eisbaer.jpg
[2] => hirsch.jpg
[3] => hundeshow.jpg
[4] => katze.jpg
[5] => panda.jpg
[6] => schimpanse.jpg
[7] => schlange.jpg
[8] => steak.jpg
)
Ordner thumbs:
Array
(
[0] => echse.jpg
[1] => eisbaer.jpg
[2] => hirsch.jpg
[3] => hundeshow2.jpg
[4] => panda.jpg
[5] => schimpanse.jpg
[6] => schlange2.jpg
[7] => steak.jpg
)In images und thumbs liegen also die Dateien mit den nicht ganz so identischen Namen. Wie zu sehen ist, gibt es ein Bild hundeshow.jpg aber ohne Thumbnail, sowie schlange.jpg ohne Thumb. Stattdessen gibt es Thumbs hundeshow2.jpg und schlang2.jpg aber ohne Image. Auch die katze.jpg steht ziemlich allein im Images Ordner. $images = glob( 'testbilder/Tierwelt/images/*.jpg' ); $thumbs = glob( 'testbilder/Tierwelt/thumbs/*.jpg' ); $images = array_map( 'basename', $images ); $thumbs = array_map( 'basename', $thumbs ); $ohne_image = array_diff( $thumbs, $images ); $ohne_thumb = array_diff( $images, $thumbs ); Die ersten 4 Zeilen könnte man auf 2 Zeilen reduzieren, aber so ist es etwas übersichtlicher. Reduziert hätten wir also gerade mal 4 Zeilen Code, um Abweichungen in beiden Verzeichnissen zu entdecken, dazu keine unnötige Schleife und das namentliche Aussortieren der Dateileichen ist bereits erledigt. Folgende Bilder haben kein zugehöriges Thumbnail:
Array
(
[3] => hundeshow.jpg
[4] => katze.jpg
[7] => schlange.jpg
)
Folgende Thumbnails haben kein zugehöriges Bild:
Array
(
[3] => hundeshow2.jpg
[6] => schlange2.jpg
)Die Ausgabe stimmt also tatsächlich mit der Liste der Dateien überein. Statt irgend welche Schleifen und Funktionen zum ausfiltern, erledigen die 3 mehr oder weniger selten benutzten, aber sehr mächtigen PHP-Funktionen. Wer meine Tutorials kennt, der hat schon häufiger die Funktion glob gesehen. Damit kann man auf einfache Art ein Verzichnis auslesen und die Dateinamen werden als Array zurück geliefert. Eine detaillierte Beschreibung spare ich mir hier, weil dies bereits im Tutorial Zufallsbild auf Seite ausgeben geschehen ist. array_map erwartet mindestens 2 Parameter. Der Erste ist eine sogenannte Callback Funktion und die Zweite ist das Array, auf die die Callback angewendet wird. Anschließend wird das so bearbeitete Array zurück gegeben. Statt nun zu schauen, welche Dateien gleich sind und die Fehlenden aufzuspüren, vergleichen wir einfach die Arrays miteinander und lassen uns von PHP direkt die Array-Elemente (Dateinamen) liefern, die nicht in beiden Arrays vorkommen. Genau das macht die Funktion array_diff für uns. Das diff ist die Kurzform für Difference, zu Deutsch Abweichung, Unterschied. Dabei wird das Array, das als erster Parameter übergeben wurde, mit dem Zweiten verglichen und alle Elemente, die im Zweiten nicht vorkommen, werden als Element eines neuen Arrays zurückgeliefert. So können wir feststellen, welche Images keine Thumbs haben und für den umgekehrten Fall drehen wir einfach die Reihenfolge der Arrays für array_diff um. Da nun klar ist, welche Dateien in welchem Ordner kein Gegenstück haben, kann man die Arrays $ohne_image und $ohne_thumb verarbeiten und das Problem aus der Welt schaffen. Ziemlich beeindruckend, wie ressourceschonend, performant und einfach man doch manchmal an's Ziel kommen kann, wenn man nur die richtigen PHP Funktionen kennt, was?! ;-) Vielen Dank für's Lesen und bis zum nächsten Kurztipp, Beispiel herunterladen (650 KB) |