Lukas: Verständnisproblem OOP

Hallo,

ich vermute mal, daß ich ein Problem zwischen Mischung aus imperativer Programmierung und OOP habe.

Ich verwende eine Klasse, die aus einem Bild ein Thumbnail erzeugen kann. Nun hätte ich aber gerne, daß diese Klasse in einer Schleife für mich arbeitet und das tut sie nicht.


<?php
include_once('inc/easyphpthumbnail.class.php');

if ($handle = opendir('./bilder')) {
    echo "Directory handle: $handle\n";
    echo "Files:\n";

    while (false !== ($file = readdir($handle))) {
    $path_parts = pathinfo($file);
    if ( $path_parts['extension']  == 'jpg' ) {
         $thumb = new easyphpthumbnail;
         // Set thumbsize - automatic resize for landscape or portrait
         $thumb -> Thumbsize = 300;
         // Create the thumbnail and output to screen
         $thumb -> Createthumb('bilder/'.$file.'');
         }
    }
    closedir($handle);
}
?>

Ergebnis ist:

Directory handle: Resource id #3 Files: ...bild1.jpgbild2.jpg usw.

Kann mir einer erklären, was ich hier falsch mache?

Gruß, Lukas

  1. Lieber Lukas,

    mit anderen Worten: Du hast keine Ahnung, was in Deiner Schleife passiert und ob sie überhaupt ausgeführt wird? Mache Dir ein paar Debug-Ausgaben, damit Du herausfindest, was in Deiner Schleife genau passiert!

    if ( $path_parts['extension']  == 'jpg' ) {

    Hast Du geprüft, ob das so passt? Was ist, wenn die Endung "jpeg" ist, oder wenn die GrOß-/kLeInScHrEiBuNg anders lautet? Wenn Du nur auf die Dateiendung prüfen willst, dann doch besser so:

    if (preg_match('~(?i)\.jpe?g$~', $file)) {

    Ich will Dir aber grundsätzlich raten, auf echte Bilddaten zu prüfen. Was ist, wenn man Dir eine Datei "bild.jpg" unterjubelt, in der tatsächlich aber keine Bilddaten, sondern eventuell PHP-Code zum Ausführen steht?

    Hier ein Auszug aus einem meiner Projekte:

    $tmp = getimagesize($file);
    $ok = (
    	$tmp[0] > 0
    	&& $tmp[1] > 0
    	&& preg_match(
    		'~(?i)\.(gif|jpeg|jpg|png)$~',
    		$file
    	)
    );
    

    Mein Code prüft nicht nur, ob die Dateiendung stimmt, sondern auch, ob es sich um gültige Bilddaten handelt. Anschließend kann ich mit if ($ok) { ... } else { ... } entsprechend reagieren.

    $thumb -> Createthumb('bilder/'.$file.'');

    Aha... Wozu das .'' nach der Variable $file? Warum nicht gleich so:

    $thumb->Createthumb("bilder/$file");

    Ergebnis ist:

    Directory handle: Resource id #3 Files: ...bild1.jpgbild2.jpg usw.

    Wie schon gesagt. Mache in der Schleife ein paar Debug-Ausgaben, damit Du weißt, was da passiert.

    Liebe Grüße,

    Felix Riesterer.

    --
    "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
    1. $thumb -> Createthumb('bilder/'.$file.'');

      Aha... Wozu das .'' nach der Variable $file?

      Hi Felix,

      war ein Versehen. Zudem ist der Code erst das Grundgerüst, weshalb ich nicht alle Prüfungen durchführe, die möglich/sinnvoll/machbar sind.

      Aber ich glaube trotzdem, daß mein Verständnisproblem zwischen imp.Prog. und OOP gerade "zuschlägt".

      Ich habe Deinen Rat befolgt und ein paar Debuganweisungen eingefügt. Dabei kommt heraus, dass es problemlos gelingt, alle Bilder des Verzeichnisses namentlich anzeigen zu lassen. Aber es gelingt nicht, die Bilder auch als Gallery darzustellen.

      Nachfolgender Code zeigt das Thumbnail des ersten Bildes des Verzeichnisses an. Mehr aber nicht. Kommentiere ich die Thumbnailerstellung aus und lasse den Echobefehl unkommentiert, dann werden hingegen alle Bilder namentlich aufgeführt.

      
      <?php
      include_once('inc/easyphpthumbnail.class.php');
      
      if ($handle = opendir('./bilder')) {
          //echo "Directory handle: $handle\n";
          //echo "Files:\n";
      
          while (false !== ($file = readdir($handle))) {
      if (($file == '.') || ($file == '..')) {
      	continue;
      }
      //echo ("$file<br>");
      $tmp = getimagesize("bilder/".$file);
      $ok = (
              $tmp[0] > 0
              && $tmp[1] > 0
              && preg_match(
                      '~(?i)\.(gif|jpeg|jpg|png)$~',
                      $file
              )
      );
      
      if ($ok) {
               $thumb = new easyphpthumbnail;
               // Set thumbsize - automatic resize for landscape or portrait
               $thumb -> Thumbsize = 300;
               // Create the thumbnail and output to screen
               $thumb -> Createthumb('bilder/'.$file);
      
      // echo("$file"); // zeigt alle Dateien namentlich an
      
      }
      
          }
          closedir($handle);
      }
      ?>
      
      

      Lukas

      1. Lieber Lukas,

        ich glaube ich habe Dein Missverständnis verstanden. Wir reden doch von dieser Klasse? Ein Link zur Heimatseite Deiner Software ist ein nicht zu unterschätzender Hinweis!

        $thumb -> Createthumb('bilder/'.$file.'');

        Dieser Aufruf erzeugt eine Ausgabe an den Browser. Die Klasse erzeugt (jedes Mal neu - ich empfehle dringend das Ergebnis zu cachen!) eine Bilddatei, ohne sie zu speichern (dazu müsstest Du den String 'file' als zweiten Parameter übertragen). Sie kann auf diese Art in Deinem HTML-Dokument referenziert werden:

        <img src="http://example.com/images/thumbnail.php?f=bild1.jpg" alt="" />

        Genau hier aber stört sich Deine Programm-Logik: Anstatt einer Bilddatei liefert der Server ein HTML-Dokument aus. Das kann der Browser nicht als Bild darstellen. Offensichtlich grätscht Dir hier aber Deine Klasse dazwischen, da der Methodenaufruf CreateThumb() Bilddaten (für genau ein Bild) an den Browser sendet und dann das PHP-Script mit Gewalt beendet (was nicht unsinnig ist).

        Es ist wesentlich sinnvoller, mit diesem PHP-Script einmal(!) die Thumbnail-Dateien zu erstellen (z.B. aus einem Admin-Bereich heraus), um sie dann in Deinem HTML-Dokument (das Du gerne mit PHP zusammenbasteln darfst) zu referenzieren. Du kannst Dein PHP-Script sogar so "schlau" machen, dass es den Bedarf an neu zu erzeugenden Thumbnail-Dateien selbst erkennt, um entsprechend zu handeln (erspart den Admin-Bereich).

        Nachfolgender Code zeigt das Thumbnail des ersten Bildes des Verzeichnisses an. Mehr aber nicht.

        Wenn der Request des Browsers nach einer Bild-Datei fragt, warum sollte Dein Script dann mehr als eine einzige solche in der Antwort senden?

        Kommentiere ich die Thumbnailerstellung aus und lasse den Echobefehl unkommentiert, dann werden hingegen alle Bilder namentlich aufgeführt.

        Deine Schleife funktioniert also.

        Mir scheint, dass Du kein Problem mit dem Verständnis von OOP hast, sondern mit dem Zusammenspiel zwischen verschiedenen PHP-Ausgaben. Ein PHP-Script kann dem Browser jede beliebige Datei mit jedem beliebigen Typ ausliefern, nicht nur HTML. Im Falle von Bildern mag es ganz bequem sein, Thumbnails nicht selbst erstellen zu müssen, sondern diese dynamisch berechnen zu lassen, man handelt sich damit aber zusätzliche Probleme ein, inklusive dem fehlenden Caching. Wenn ich mit einem PHP-Script (nennen wir es der Einfachheit halber "index.php") ein HTML-Dokument generiere, in dem eine Bilddatei nach obigem Muster defniniert ist, dann benötige ich ein zweites Script, das mir diese Datei (bei Bedarf generiert und) ausgibt. In diesem zweiten Script kannst Du Deine Klasse einsetzen.

        Natürlich kann man ein PHP-Script so intelligent basteln, dass es versteht, ob gerade ein HTML-Dokument, oder eine darin referenzierte Datei (und welche!) angefordert wurde, um aus den eben skizzierten zwei Scripts ein einzelnes zu machen. Aber dazu muss man den prinzipiellen Mechanismus verstanden haben, dass das einzelne Script dann mehrfach vom Browser mit unterschiedlichen Anfragen aufgerufen werden kann.

        Grundsätzlich könntest Du die Bilddaten auch im HTML-Dokument direkt ausgeben, aber dann verlierst Du den Vorteil des Cachings erneut.

        Liebe Grüße,

        Felix Riesterer.

        --
        "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
        1. Hi Felix,

          Mir scheint, dass Du kein Problem mit dem Verständnis von OOP hast, sondern mit dem Zusammenspiel zwischen verschiedenen PHP-Ausgaben. Ein PHP-Script kann dem Browser jede beliebige Datei mit jedem beliebigen Typ ausliefern, nicht nur HTML. Im Falle von Bildern mag es ganz bequem sein, Thumbnails nicht selbst erstellen zu müssen, sondern diese dynamisch berechnen zu lassen, man handelt sich damit aber zusätzliche Probleme ein, inklusive dem fehlenden Caching. Wenn ich mit einem PHP-Script (nennen wir es der Einfachheit halber "index.php") ein HTML-Dokument generiere, in dem eine Bilddatei nach obigem Muster defniniert ist, dann benötige ich ein zweites Script, das mir diese Datei (bei Bedarf generiert und) ausgibt. In diesem zweiten Script kannst Du Deine Klasse einsetzen.

          Genau so ist es und genau so habe ich das gestern abend dann noch gelöst. Ich habe die HTML generierende php-Datei komplett von der das Thumbnail generierenden Datei gelöst und zweitere Datei "bedient" dann auch die Klasse selber.

          So erhalte ich dann im "HTML" auch beliebig viele Thumbnails.

          Da ich das ganze mit einer Datenbank unterfüttere, könnte ich die Thumbs auch bereits beim Upload bequem mitspeichern, sodaß das Chaching eh kein weiter zu berücksichtigendes Kriterium mehr wäre.

          Gruß, Lukas

  2. Hallo Lukas,

    ich bin schon länger auf der Suche nach einer guten "thumbnail Class". Verwendest du in deinem Script diese? http://www.mywebmymail.com/?q=content/easyphpthumbnail-class und hast du damit bereits Erfahrungen sammeln können?

    1. Hallo Lukas,

      ich bin schon länger auf der Suche nach einer guten "thumbnail Class". Verwendest du in deinem Script diese? http://www.mywebmymail.com/?q=content/easyphpthumbnail-class und hast du damit bereits Erfahrungen sammeln können?

      Hi,

      ja, die verwende ich, habe sie aber selber gestern erst gefunden. Erster Eindruck ist gut, aber "Erfahrung mit dieser Class" wäre übertrieben.

      Lukas