Alex: Dateinamen eines Verzeichnisses einlesen

Hallo,

ich bin da gerade was am planen dran:

Ich will eine Bildergalerie schreiben, was für mich eine riesen Herausforderung ist, weil ich - wie ihr gleich merken werdet - noch nicht sehr fit in PHP und MySQL bin.

Ich habe meine Bilder (001.jpg, 002.jpg ...) in unterschiedlichen Ordnern abgelegt (album_1, album_2 ...). Die Tabelle für die Alben kriege ich noch hin (Spalten: alben_id, albumname, beschreibung, pfad und noch so nen paar). Bei der Tabelle für die Bilder (Spalten: bilder_id, alben_id, bildname, beschreibung) weiß ich nicht, wie ich die Bilder bzw. nur die Bildnamen (z.B. 001.jpg) eines bestimmten Verzeichnisses einlesen kann und in die Tabelle einfügen kann. Also in etwa so:

bild_id --- alben_id --- bildname --- beschreibung
1       --- album_1  --- 001.jpg  --- ...

Die Beschreibung will ich bei Bedarf manuell ergänzen. Aber das ausfüllen der ersten Spalten müsste doch "automatisiert" gehen dürfen, oder? Also die Bildnamen in ein Array einzulesen habe ich schonmal an anderer Stelle geschafft, ist das der richtige Startpunkt und ich kümmer mich dann nur noch darum, die Namen aus dem Array in die DB zu bekommen (wobei ich dann wieder vor der Frage stehe, wie?)? Oder gibt es da was einfacheres?

Vlt. denke ich zur zeit noch zu theoretisch, weil ich erstmal planen wollte, bevor ich drauf los tippe. Ich wollte mir aber auch im Vorfeld nichts verbauen und die Tabellenstrukturen usw. erstmal auf nen "Blatt Papier" durchdenken.

  1. Hallo,

    wenn ich dich richtig verstanden habe, dann geht es dir darum wie man alle Bilder (jpgs) eines Verzeichnisses in eine DB Tabelle bekommt?

    Warum liest du nicht einfach ein Verzeichnis ein und schreibst dann alle gefunden Dateien in die DB?

    <<$dh = opendir($useruploadtmp);
    while ($entry = readdir($dh)){
    HIER DANN DEIN INSERT

    Gruss
    hawk

  2. Moin

    du suchst opendir() und readdir() in Verbindung mit einer whileschleife.

    Gruß Bobby

    --
    -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
    -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
    ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
    1. Glück auf!

      opendir() und readdir() in Verbindung mit einer whileschleife.

      So habe ich das bisher gemacht, um die Bilder in das Array "Bilder" zu bekommen (in der Variablen $verzeichnis steht dann z. B. "album_1":

      $dir = opendir ("../$verzeichnis");
      while ($bild = readdir ($dir)){
       if ($bild != "." && $bild != "..")
      $bilder[] = $bild;
      }
      closedir($dir);

      Aber jetzt will ich, dass je Bild ein Datensatz in der DB erstellt wird. Bisher arbeite ich mit MySQL fast ausschließlich über phpmyadmin und gebe die Daten da ein. Deswegen frage ich mich, wie ich die Daten per Script in die Tabelle kriege.(?)

      1. Hallo
        da hast du es doch schon!

        $dir = opendir ("../$verzeichnis");
        while ($bild = readdir ($dir)){
        if ($bild != "." && $bild != "..")

        hier deinen INSERT INTO setzen

        }
        closedir($dir);

        Gruß Rainer

        1. Hallo
          da hast du es doch schon!

          Hhhm, ich hatte mir das komplizierter vorgestellt.

          $dir = opendir ("../$verzeichnis");
          while ($bild = readdir ($dir)){
          if ($bild != "." && $bild != "..")

          hier deinen INSERT INTO setzen

          }
          closedir($dir);

          Ich versuch das nachher Zuhause mal. Vielen Dank schonmal an euch alle. Wenn ich es nicht hinkriege hört ihr heute Abend nochmal von mir :)

          1. Moin!

            $dir = opendir ("../$verzeichnis");
            while ($bild = readdir ($dir)){
            if ($bild != "." && $bild != "..")

            hier deinen INSERT INTO setzen

            Hhhm, ich hatte mir das komplizierter vorgestellt.

            Das kann es noch werden.

            Wenn du diesen Code erstellst und ausführst, wird dir pro Skriptlauf jedes im Verzeichnis befindliche Bild in die Datenbank geschrieben. Beim zweiten Skriptlauf hast du dann jedes Bild schon doppelt drin.

            Ob das im normalen Betrieb passiert, hängt davon ab, welchen Weg deine Bilder nehmen, um in die Galerie bzw. die Datenbank zu gelangen. Nicht unüblich ist, ein Formular mit Upload-Feldern zu haben, in die man jedes Bild einzeln eintragen muß. Sehr mühsam - aber der Eintragungscode würde dann gar kein Verzeichnis durchscannen, sondern müßte die hochgeladenen Bilder nur in das passende Verzeichnis verschieben und den Dateinamen dann in die DB eintragen.

            Fortgeschrittenere Methoden erlauben auch das Hochladenen mehrerer Bilder, die sich in einer einzelnen ZIP-Datei befinden. Das zu realisieren ist aber noch komplexer, weil man das ZIP natürlich auspacken muß.

            Beide Ansätze sind unsinnig, wenn man direkten Zugriff auf das Verzeichnis hat, welches das Skript als Auslieferungslager für die spätere Bildanzeige nutzt (lokale Festplatte, FTP, SCP, ...). Wenn also der Arbeitsablauf vorsieht, dass du einfach die neuen Dateien in das festgelegte Verzeichnis bzw. in dortige Unterverzeichnisse packst, und dein Skript diese Struktur neu indizieren soll, dann ist es logisch, dass du berücksichtigen mußt, ob die Datei vorher schon einmal indiziert wurde - in diesem Fall darf sie natürlich nicht als neues Bild in die Datenbank geschrieben werden - allenfalls dürfen Dateiinformationen, die sich zwischenzeitlich geändert haben, aktualisiert werden.

            Am einfachsten dürfte sein, wenn du der Datenbank das Auffinden von Duplikaten überläßt. Wenn festgelegt ist, dass jeder Dateiname einmalig sein muß, dann setze einen UNIQUE-Index auf die Spalte mit dem Dateinamen. INSERTs, die schon vorhandene Dateinamen einfügen wollen, scheitern dann mit einer SQL-Fehlermeldung (die du mit mysql_error() bzw. mysql_errno() abfragen kannst - die Fehlernummer abzufragen ist sicherlich leichter, weil die Nummer für "Duplicate Entry" sich nicht ändert, egal welche MySQL-Version, und du diesen erwarteten Fehler dann nicht dem User melden mußt - alle anderen natürlich schon).

            Wenn du Unterverzeichnisse benutzt, müßte die UNIQUE-Spalte entweder den vollen oder anteiligen Pfadnamen enthalten, oder alternativ gibt es zwei Spalten (Pfad und Dateiname getrennt), über die ein gemeinsamer UNIQUE-Index gelegt wird (dann muß die Kombination beider Felder einmalig sein - kommt aufs gleiche raus, ist aber eventuell aus Sicht der Tabellen-Struktur günstiger - hängt davon ab, was du mit den Feldinformationen noch so vor hast, außer die Datei wiederzufinden).

            Du siehst: Das Thema ist weitaus komplexer, als man es auf den ersten Blick sieht - aber beginne am besten wirklich ganz einfach, denn alle Komplizierungen ergeben sich erst, nachdem du die erste, noch humpelnde Version geschrieben hast, und auf deren Unzulänglichkeiten gestoßen bist - Lerneffekt. ;)

            - Sven Rautenberg

            --
            "Love your nation - respect the others."
            1. Hallo Sven!

              Danke, dass du mir ein paar mögliche Komplikationen aufgezeigt hast. Tatsächlich existieren die Bilder in einem Ordner (Album), welches nur einmal durchlaufen wird (innerhalb eines Ordners sind die Bilder aufsteigend nach ###, beginnend bei 001 benannt). 001.jpg existiert also des öfteren, jedoch in unterschiedlichen Ordnern. Vlt. werde ich die Bilder aber auch unbenennen (z.B. in album1_001.jpg), damit sie eindeutig sind und ich somit mit deinen weiteren Tipp arbeiten kann.

              Alles in allem bin ich aber auch erstmal mit einer "halbperfekten" ;-) Lösung zufrieden und versuche es zu vermeiden, ein Verzeichnis doppelt einzulesen.

              Neben deinen hilfreichen Tipps auch danke für das Mut machen in deinem letzten Absatz.

              1. Moin!

                Danke, dass du mir ein paar mögliche Komplikationen aufgezeigt hast. Tatsächlich existieren die Bilder in einem Ordner (Album), welches nur einmal durchlaufen wird (innerhalb eines Ordners sind die Bilder aufsteigend nach ###, beginnend bei 001 benannt). 001.jpg existiert also des öfteren, jedoch in unterschiedlichen Ordnern. Vlt. werde ich die Bilder aber auch unbenennen (z.B. in album1_001.jpg), damit sie eindeutig sind und ich somit mit deinen weiteren Tipp arbeiten kann.

                Es gibt auch noch eine recht "simple" Alternativlösung: Lege dir einfach zwei Verzeichnisbäume an. Der eine Baum wird final zum Ausliefern der indizierten Bilder genutzt. Der zweite Baum ist nur dazu da, dort neue Bilder zu platzieren. Und beim Indizieren wird nur diese Verzeichnisstruktur durchlaufen, und alle gefundenen Bilder werden in den finalen Verzeichnisbaum verschoben.

                Hat den Vorteil, dass du dein Skript so häufig wie notwendig durchlaufen lassen kannst, ohne dass es allzu komplex wird.

                Man kann - unabhängig vom Verschieben oder Duplikatfinden - auch noch den Ansatz wählen, in die DB integrierte Bilder automatisch nach DB-Kriterien umzubenennen, z.B. nach der in der DB zugeordneten Bild-ID, oder indem man z.B. die Stichworte oder Bildtitel in den Dateinamen mit integriert.

                Die ID-Variante hat den Vorteil, dass du automatisch eindeutige Dateinamen erhältst, weil die IDs eindeutig sind. Die Namensvariante (ggf. als Anhängsel an die ID) hätte den zusätzlichen Vorteil, dass du die Bildersammlung auch mit einer ganz normalen Dateisuche nach eventuellen Stichworten durchsuchen kannst, ohne deine Datenbank zu benötigen (iTunes kann sowas z.B. mit seinen MP3-Dateien machen, schön in Verzeichnissen sortiert Interpret/Album/Titel, mit dynamischer Umbenennung, wenn man im Programm was ändert oder korrigiert).

                - Sven Rautenberg

                --
                "Love your nation - respect the others."