Helmut: Dateien aus Verzeichnis auslesen und Tabelle erstellen

Hallo liebe SELFHTMLer,

zunächst gleich zu beginn: ich bin noch blutiger PHP-Anfänger der sich gerade seine ersten Versuche hinter sich hat. Aus dem Grund würde ich mich eigentlich gar nicht trauen hier nachzufragen. Seit einigen Stunden versuche ich allerdings eine Idee zu realisieren bei der mir langsam der Kopf raucht. Vielleicht könnt ihr mir bei dme folgenden Problem auf die Schwünge helfen:

Ich möchte eine Tabelle mit Bildern erzeugen. Die Bilder liegen in einem Verzeichnis (bilder) und sind mit 001.jpg, 002.jpg usw. benannt. Für jedes Bild soll eine eigene Zelle in einer Tabelle erzeugt werden. Die Tabelle soll am Ende 7x3 Zellen haben wenn sie voll ist. Das Problem: wie kann ich die Bilder der Reihe nach auslesen, bei 7 und 14 Bildern einen Zeilensprung machen (<tr>) und bei 21 Bilder eine Neue Tabelle anfangen?

Zum verdeutlichen habe ich mal meine Denkhilfe hochgeladen:

http://img230.imageshack.us/my.php?image=tablesu1.jpg

Mein chaotisches Script sieht bis jetzt folgendermaßen aus:

<script language="php">  
  
$verzeichnisname = "html/ad/sh/test/bilder";  
  
$verzeichnis = opendir($verzeichnisname);  
  
echo "<table width=\"801\" border=\"0\">  
  <tr>";  
  
while($eintrag = readdir ($verzeichnis))  
{  
  $test = $verzeichnisname . "/" . $eintrag;  
  
   $parts = explode('.', $eintrag);  
 $endung = array_pop($parts);  
 $name = join('', $parts);  
 echo $name;  
  
  if(is_dir($test) or (($eintrag==".htaccess") ))  
    {  
     // echo "<!-- $eintrag -->\n";  
    }  
  else  
     {  
     echo "<td align=\"center\"><img src=\"bilder/";echo $eintrag."\"></td>\n";  
  
     }  
}  
closedir($verzeichnis);  
echo   "</tr>  
</table>";  
</script>

Das erste Problem: in dem Verzeichnis sind auch Dateien wie 001.txt - für die erstellt er jetzt auch Bilder und <td>-tags. Ich möchte eigentlich nur, dass die 001.jpg, 002.jpg der Reihe nach durchgegangen und aufgelistet werden. Am meisten Kopfzerbrechen bereitet mir aber der Zeilensprung bei 7 und 14, gar nicht zu denken an den Seitensprung bei 21 vorgefundenen Bildern. Und gerade bin ich an dem Punkt wo ich denke ich verstehe wieder überhaupt nichts...

vielen Dank schon einmal für Unterstützung!

  1. Hello,

    Mein chaotisches Script sieht bis jetzt folgendermaßen aus:

    Trenne in drei wesentliche Funktionen und eine Steuerung

    0. Einstellungen festlegen
       - Bilderverzeichnis
       - Bildtypen (Muster für glob())
       - Anzahl Bilder pro Zeile
       - Zeilen pro Tabelle

    1. Verzeichnis auslesen
       Ressource-Bezeichner beschaffen
       prüfen, ob es alles Bilder sind
       Array bereitstellen
       Daraus ergibt sich auch die Anzahl der Seiten

    Das Array kann evtl auch zwischengespeichert werden

    2. Funktion für das Zeilenerzeugen (speichert das Ergebnis in einem String)

    3. aus Zeilen Tabelle bauen (speichert das Ergebnis in einem String)

    4. Links auf weitere Seiten berechnen (speichert das Ergebnis in einem String)

    Erst jetzt die ganze Seite ausgeben lassen.

    Vielleicht ist dafür der Thread http://forum.de.selfhtml.org/archiv/2008/8/t175925/#m1159112 für Dich von Interesse. Wie man eine ganze Bildergalerie baut, kann Malcolm Beck's Dir posten...

    Liebe Grüße aus Syburg bei Dortmund

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Danke Tom! Hab mich heute damit beschäftigt und durchgeschlagen und kam auch einigermaßen voran. Das Script ist nun schon soweit, dass es die Bilder korekt anzeigt, nach jeweils 8 horizontalen Bildern einen Zeilensprung macht und nach 24 Bildern aufhört. Nur Klappt das mit der Seitenweisen darstellung nicht, falls es mehr als 24 Bilder sind. Momentan zeigt er mir sowohl bei Seite=1 und Seite=2 die ersten 24 Bilder an! Ich weiss es ist schwierig sich in einen anderen Code reinzudenken, aber könnte jemand vielleicht mal schauen ob ich diese while schleife richtig drin habe? irgendetwas stimmt da nicht und ich komm nicht drauf.

      <?php  
       $seite = $_REQUEST['seite']; //seitennummer aus url übernehmen  
       if (!isset($seite)) {$seite = "1";}  //wenn seitennummer nicht übergeben  
       $startbild = "1";  
       if ($seite == 2) { $startbild = "25"; }  
       if ($seite == 3) { $startbild = "50"; }  
       if ($seite == 4) { $startbild = "75"; }  
        
        
        
      // bilder anzeigen  
       $count = 0;  
       $zeilensprung = 1;  
       $seitensprung = 0;  
       //echo "Startbild: ".$startbild." Seitensprung: ".$seitensprung." Count: ".$count;  
       $bilder = glob( "projekte/thumbs/*.jpg" );  
       natsort( $bilder );  
       foreach ($bilder as $bild)  
       {  
       while ($count < $startbild) {  
        $count++;  
       }  
       if ($count >=$startbild) {  
        $bild = array_pop( explode( "/", $bild ) );  
        $name = explode(".",$bild);  
        //echo "Name: " . $array_file[0] . "<br>";  
        //echo "Endung: " . $array_file[1] . "<br>";  
        
        echo '<a href="projekt.php?projekt=' .urlencode( $name[0] ). '" title="" class="thumb"><img src="projekte/thumbs/' .$bild. '" /></a>';  
        echo ($zeilensprung % 8 == 0) ? "<br />\n" : "";  
        $zeilensprung++;  
        $seitensprung++;  
        if ($seitensprung == 24) {  
           break;  
           }  
        }  
       }  
        
      ?>
      
      1. Hi,

        Nur Klappt das mit der Seitenweisen darstellung nicht, falls es mehr als 24 Bilder sind. Momentan zeigt er mir sowohl bei Seite=1 und Seite=2 die ersten 24 Bilder an!

        Hast du Seite=1 mit großem oder kleinem 'S' versucht?

        <?php

        $seite = $_REQUEST['seite']; //seitennummer aus url übernehmen

        Ich würde hier $_GET statt $_REQUEST verwenden.

        if (!isset($seite)) {$seite = "1";}  //wenn seitennummer nicht übergeben
        $startbild = "1";
        if ($seite == 2) { $startbild = "25"; }
        if ($seite == 3) { $startbild = "50"; }
        if ($seite == 4) { $startbild = "75"; }

        Das würde ich mit if,elsif,else machen, dann hast du auch alle Fälle abgedeckt, die du so nicht erwischt. Z.B. wenn jemand seite=7 eingibt.

        Außerdem stimmt da was nicht glaub ich. von 1 auf 25 sinds 24, aber von 25 auf 50 sinds 25 Unterschied.

        // bilder anzeigen
        $count = 0;
        $zeilensprung = 1;
        $seitensprung = 0;
        //echo "Startbild: ".$startbild." Seitensprung: ".$seitensprung." Count: ".$count;
        $bilder = glob( "projekte/thumbs/*.jpg" );
        natsort( $bilder );
        foreach ($bilder as $bild)
        {
        while ($count < $startbild) {
          $count++;
        }

        Diese Schleife setzt $count auf $startbild.
        Das könntest du auch mit $count = $startbild erreichten.
        Aber ich glaube du möchtest die Schleife weglassen und nur $count bei jedem Durchlauf der äußeren for-Schleife um 1 erhöhen.

        if ($count >=$startbild) {

        Das ist hier momentan immer true.
        Aber wenn du $count nur jedesmal um eins hochzählst müsste es passen.

        $bild = array_pop( explode( "/", $bild ) );
          $name = explode(".",$bild);
          //echo "Name: " . $array_file[0] . "<br>";
          //echo "Endung: " . $array_file[1] . "<br>";

        echo '<a href="projekt.php?projekt=' .urlencode( $name[0] ). '" title="" class="thumb"><img src="projekte/thumbs/' .$bild. '" /></a>';
          echo ($zeilensprung % 8 == 0) ? "<br />\n" : "";
          $zeilensprung++;
          $seitensprung++;
          if ($seitensprung == 24) {
             break;
             }
          }
        }

        ?>

        
        >   
        
        mfG,  
        steckl
        
        1. danke steckl für die Hinweise! Hatte ja schon das Problem mit der Schleife gelöst, aber danke nochmal für die Erkärung! Ist mir jetzt auch um einiges klarer. Und die anderen Fehler hatte ich bis jetzt auch noch nicht bemerkt.

          1. Oh, irgendwie ging mein Post verloren der die Lösung beschrieb. Also hier mein fertiges Script:

            $seite = $_GET['seite']; //seitennummer aus url übernehmen  
             if (!isset($seite)) {$seite = "1";}  //wenn seitennummer nicht übergeben  
             $startbild = "1";  
             if ($seite == 2) { $startbild = "25"; }  
             if ($seite == 3) { $startbild = "49"; }  
             if ($seite == 4) { $startbild = "73"; }  
              
              
             $count = 0;  
             $zeilensprung = 1;  
             $bilder = glob( "projekte/thumbs/*.jpg" );  
             natsort( $bilder );  
             foreach ($bilder as $bild) {  
               if ($count < $startbild) {  
                $count++;  
                }  
               if ($count >=$startbild) {  
                $bild = array_pop( explode( "/", $bild ) );  
                $name = explode(".",$bild);  
                echo '<a href="projekt.php?projekt=' .urlencode( $name[0] ). '" title="" class="thumb"><img src="projekte/thumbs/' .$bild. '" /></a>';  
                echo ($zeilensprung % 8 == 0) ? "<br />\n" : "";  
                $zeilensprung++;  
                if ($zeilensprung == 25) {  
                    break;  
                 }  
              
                  }  
               }
            

            funktioniert wunderbar. Bin glücklich. Danke an alle :-)

            1. Mahlzeit Helmut,

              Oh, irgendwie ging mein Post verloren der die Lösung beschrieb. Also hier mein fertiges Script:

              Nein, das ist noch nicht fertig.

              $seite = $_GET['seite']; //seitennummer aus url übernehmen

              if (!isset($seite)) {$seite = "1";}  //wenn seitennummer nicht übergeben
              $startbild = "1";
              if ($seite == 2) { $startbild = "25"; }
              if ($seite == 3) { $startbild = "49"; }
              if ($seite == 4) { $startbild = "73"; }

                
              Einerseits frage ich mich, wieso Du numerische Werte unbedingt als Strings abspeichern willst, andererseits hilft Dir - [wie Auge bereits schrieb](https://forum.selfhtml.org/?t=176596&m=1162437) - diese unschöne Konstruktion nicht, wenn es mal mehr Bilder werden: Du müsstest jedesmal den Code anpassen. Auge hat auch bereits eine hilfreiches Codefragment genannt, ich selbst würde es etwas anders machen ...  
                
              `$startbild = max(1, ($seite - 1) * 24 + 1);`{:.language-php}  
                
              ... aber das kommt ja im Endeffekt aufs Gleiche hinaus.  
                
                
              MfG,  
              EKKi  
              
              -- 
              sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
              
      2. Hallo

        Nur Klappt das mit der Seitenweisen darstellung nicht, falls es mehr als 24 Bilder sind. Momentan zeigt er mir sowohl bei Seite=1 und Seite=2 die ersten 24 Bilder an! Ich weiss es ist schwierig sich in einen anderen Code reinzudenken, aber könnte jemand vielleicht mal schauen ob ich diese while schleife richtig drin habe? irgendetwas stimmt da nicht und ich komm nicht drauf.

        <?php

        $seite = $_REQUEST['seite']; //seitennummer aus url übernehmen

          
        Das Umkopieren dieses Wertes ist unnötig. Er liegt ja schon vor. Allerdings solltest du anstatt `$_REQUEST`{:.language-php} `$_GET`{:.language-php} bzw. `$_POST`{:.language-php} benutzen, da du dir damit zumindest des Übertragungsweges sicher sein kannst. Zusätzlich solltest du noch die Plausibilität des Wertes prüfen. Es kommt immer nur ein String an, der muss aber numerisch sein, das kannst du mit [is_numeric](http://www.php.net/is_numeric) prüfen. Leider kann man der Funktion keine Zahlenbasis übergeben, so dass sie nicht zwischen dezimalen Zahlen (was hier der Fall ist) oder binären, oktalen, hexadezimalen und was es sonst noch gibt unterscheidet. Mehr zur Prüfung unten.  
          
        
        > ~~~php
        
         if (!isset($seite)) {$seite = "1";}  //wenn seitennummer nicht übergeben  
        
        >  $startbild = "1";  
        >  if ($seite == 2) { $startbild = "25"; }  
        >  if ($seite == 3) { $startbild = "50"; }  
        >  if ($seite == 4) { $startbild = "75"; }
        
        

        Was machst du, wenn es mal mehr Bilder und damit auch mehr Seiten werden? Besser wäre eine entsprechende Berechnung. Ungefähr so:

        if ($seite>1) {  
        $startbild = ($seite-1)*24+1;  
        } else {  
        $startbild = 1;  
        }  
        // gibt z.B. für Seite3 49 aus (Seiten 1 & 2 zeigen die ersten 48 Bilder an)  
        
        

        ...
        $bilder = glob( "projekte/thumbs/*.jpg" );
        ...

          
        Es wäre besser, dem Auslesen des verzeichnisses gleich das Filtern folgen zu lassen. Mit [array_slice](http://www.php.net/array_slice) kannst du dir einen Ausschnitt eines Arrays zurückgeben lassen.  
          
        ~~~php
        $bilder = array_slice($bilder,$startbild,24);  
        // gibt die Elemente von 24 Bildern ab dem Wert von $startbild zurück
        

        Jetzt hast du nur noch die 24 anzuzeigenden Bilder im Array $bilder. Die für die Vor-Zurück-Navigation notwendigen Werte kannst du aus $seite ermittlen.

        Nochmal wegen der Prüfung vom $seite. Oben habe ich dir gezeigt, wie man den Wert darauf prüft, ob er aus Ziffern besteht. Wenn du die Vor-Zurück-Navigation sauber aufbaust, wirst du bei der letzten Seite keine Vor-Navigation anbieten. Dennoch kann ein Benutzer auf einfachste Weise (zumindest, wenn $seite als URL-Parameter übergeben wird) einen größeren oder allgemeiner ungültigen Wert übergeben. Wenn du zwischen dem Auslesen des Verzeichnisses und dem Filtern nach den gewünschten Bildernamen mit count noch die Gesamtanzahl der Bilder ermittelst und daraus die Gesamtzahl der Seiten errechnest, kannst du solche Eingaben auch noch ausfiltern.

        // NACH dem Auslesen mit glob UND VOR dem Filtern mit array_slice!  
        $alle_seiten = ceil(count($bilder)/24);  
        // wenn ich nicht irre  
          
        // count zählt die Anzahl der Elemente in $bilder  
        // ceil rundet zur nächsten ganzen Zahl auf
        

        Mit range baust du dir daraus ein Array, in dessen Wertebereich $seite enthalten sein muss. Prüfen kannst du das mit in_array.

        Tschö, Auge

        --
        Die deutschen Interessen werden am Liechtenstein verteidigt.
        Veranstaltungsdatenbank Vdb 0.2