[PHP] Thumbnailklasse

Dieses Thema im Forum "Webentwicklung" wurde erstellt von MakenX, 29. Oktober 2006 .

Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. 29. Oktober 2006
    Thumbnailklasse

    Hab für ein aktuelles Projekt mal ne neue Thumbnailklasse gemacht.
    So vorweg PHP 5 (und falls cleanaufruf mit datenbankhandle mysqli) wird benötigt. Bitte äußerst auch Kritik, oder ob ich was besser machen könnte oder euch das script gefällt!?

    PHP:
    <? php
     

        
    function  checkid ( $id ) {
            if(!
    is_numeric ( $id )) { $id  FALSE ; //Ist der Wert bei grober Unterscheidung keine Zahl so ist er FALSE
            
    } else { $id  intval ( $id );} //Ein möglicher Zahlenwert wird in Integer
            //If Kontrolle ob ein Integerwert erzeugt werden konnte...
            
    if( $id  ===  FALSE  OR  settype ( $id "integer" ) ===  FALSE  OR  is_infinite ( $id )) {die( errorhandling ( 'index.php' 7 ));} //...Fehlermeldung falls nein
            
    else {return  $id ;} //...Integer Returnwert falls ja
        
    } //Ende checkid($id)

        /**
         * clean() - Validiert Nutzereingaben
         * 
         * Zu Beginn wird überprüft ob MagicQuotes an sind, falls ja wird der String mit stripslashes gewrappt.
         * Anschließend werden mögliche Zeichen in URI - Konforme Zeichen umgewandelt und möglicher Schad-
         * code komplett entfernt.
         *
         * @param $db -> Falls angegeben wird der Wert durch mysqli_real_escape_string geschickt
         * @param string $string -> Usereingabe
         * @return string
         */
        
    function  clean ( $string $db  FALSE ) {
            if(
    get_magic_quotes_runtime () ==  TRUE  OR  get_magic_quotes_gpc () ==  TRUE ) { $string  stripcslashes ( $string );} //Bei magic quotes
            
    $string  trim ( $string ); //Whitespace entfernen
            
    $string  htmlspecialchars ( strip_tags ( $string ),  ENT_QUOTES ); //Sonderzeichen URI kompatibel kodieren
            
    if( $db  ==  TRUE ) {return  $db -> real_escape_string ( $string ); //Return Wert für eine Datenbankverwendung
            
    } else {return  $string ;}
        }
    //Ende clean($string)

        /**
         * final class thumbnail - Erstellung eines Thumbnails
         *
         * Diese Klasse erstellt falls nötig ein Thumbnail des Originalbildes wenn entweder noch keins vorhanden ist oder das Originalbild neuer als das Thumbnail ist.
         *
         */
        
    final class  thumbnail  {
            

            
    private  $_ioriginaldate ;

            

            
    private  $_ithumbnaildate ;

            

            
    private  $_ithumbnailwidth ;

            

            
    private  $_soriginalfile ;

            

            
    private  $_sthumbnailfile ;

            

            
    private  $_sthumbnailprefix ;

            

            
    public function  __construct ( $thumbnailwidth  100 $thumbnailprefix  'tn_' ) {
                
    //Startwerte
                
    $this -> _ithumbnailwidth  checkid ( $thumbnailwidth ); //Breite des Thumbnails
                
    $this -> _sthumbnailprefix  clean ( $thumbnailprefix );
                unset(
    $thumbnailwidth $thumbnailprefix ); //Alte Variablen löschen
            
    } //Ende Konstruktor

            /**
             * Destruktor
             *
             * Der Destruktor löscht den Speicher von allen Klassenattributen
             *
             */
            
    public function  __destruct () {
                unset(
    $this -> _ioriginaldate $this -> _ithumbnaildate $this -> _ithumbnailwidth $this -> _soriginalfile $this -> _sthumbnailfile $this -> _sthumbnailprefix ); //Variablen löschen
            
    } //Ende Destruktor

            /**
             * makethumbnail() - Thumbnailerstellung
             *
             * Diese Funktion bestimmt die Größe und proportionale Breite des Thumbnails und erstellt nach dem jeweiligen Dateityp einen Thumbnail.
             *
             */
            
    private function  makethumbnail () {
                
    $srcfileinfo  getimagesize ( $this -> _soriginalfile ); //Bildinfos einlesen
                
    $height = (int) round (( $srcfileinfo [ 1 ]* $this -> _ithumbnailwidth / $srcfileinfo [ 0 ]),  2 ); //Die Höhe des Thumbnails erstellen
                
    $thumb  imagecreatetruecolor ( $this -> _ithumbnailwidth $height ); //Bildplatzhalter erstellen
                
    if( $srcfileinfo [ 2 ] ===  1 ) { //IF Verzweigung nach Dateityp - beginnend mit dem Gif - Zweig
                    
    $source  ImageCreatefromgif ( $this -> _soriginalfile ); //Handle auf Originalbild
                    
    imagecopyresized ( $thumb $source 0 0 0 0 $this -> _ithumbnailwidth $height $srcfileinfo [ 0 ],  $srcfileinfo [ 1 ]); //Thumb speichern
                    
    imagegif ( $thumb $this -> _sthumbnailfile ); //Bild speichern
                
    } elseif( $srcfileinfo [ 2 ] ===  2 ) { //JPG - Zweig
                    
    $source  ImageCreatefromjpeg ( $this -> _soriginalfile ); //Handle auf Originalbild
                    
    imagecopyresized ( $thumb $source 0 0 0 0 $this -> _ithumbnailwidth $height $srcfileinfo [ 0 ],  $srcfileinfo [ 1 ]); //Thumb speichern
                    
    imagejpeg ( $thumb $this -> _sthumbnailfile ); //Bild speichern
                
    } elseif( $srcfileinfo [ 2 ] ===  3 ) { //PNG - Zweig
                    
    $source  ImageCreatefrompng ( $this -> _soriginalfile ); //Handle auf Originalbild
                    
    imagecopyresized ( $thumb $source 0 0 0 0 $this -> _ithumbnailwidth $height $srcfileinfo [ 0 ],  $srcfileinfo [ 1 ]); //Thumb speichern
                    
    imagepng ( $thumb $this -> _sthumbnailfile ); //Bild speichern
                
    } //Ende IF Verzweigung nach Dateityp
                
    unset( $this -> _ithumbnailwidth $srcfileinfo $height $thumb $source ); //Alte Dateien löschen
            
    } //Ende makethumbnail()

            /**
             * show() - Ausgabe des Thumbnails
             *
             * Diese Methode überprüft zu Beginn ob überhaupt schon ein Thumbnail vorhanden oder dieser älter als die Originaldate ist. Falls ja wird ein neuer Thumbnail erstellt und anschließend der Pfad zurückgegeben
             *
             * @param string $origin -> Dateiname der Originaldatei
             * @param string $path -> Pfad wo das Thumbnail liegen soll
             * @return string
             */
            
    public function  show ( $origin $path  './' ) {
                
    //Pfaderstellung
                
    $origin  clean ( basename ( $origin )); //Falls ein kompletter Pfad übergeben wurde, bereinige die Angabe zusätzlich von Schadcode
                
    $this -> _soriginalfile  $path . $origin ; //Pfad zur Originaldatei auslesen
                
    $this -> _sthumbnailfile  $path . $this -> _sthumbnailprefix . $origin ; //Pfad zur Originaldatei auslesen
                
    unset( $origin $path );
                
    //Ende Pfaderstellung

                //Timestamps der Änderungsdaten des Thumbnails under der Originaldatei
    @             $this -> _ioriginaldate  filemtime ( $this -> _soriginalfile ); //Timestamp der Originaldatei erstellen
    @             $this -> _ithumbnaildate  filemtime ( $this -> _sthumbnailfile ); //Timestamp des Thumbnails erstellen
                //Ende Timestamps der Änderungsdaten des Thumbnails under der Originaldatei

                //Ist die Originaldatei neuer als der Thumbnail so erstelle ein neues Thumbnail
                
    if( $this -> _ithumbnaildate  ===  FALSE  OR  $this -> _ioriginaldate  >=  $this -> _ithumbnaildate ) {
    @                
    unlink ( $this -> _sthumbnailfile ); //Alte Datei löschen
                    
    $this -> makethumbnail (); //Neue Datei erstellen
                
    } //Ende - //Ist die Originaldatei neuer als der Thumbnail so erstelle ein neues Thumbnail
                
    return  $this -> _sthumbnailfile ; //Pfad zum Thumbnail zurück geben
            
    } //Ende show
        
    } //Ende final class thumbnail
    ?>
    Öffentliche Funktionen:
    thumbnail::__construct($thumbnailwidth = 100, $thumbnailprefix = 'tn_');//Thumbnailklasse initialisieren
    thumbnail::show($origin, $path = ./);//erstellt das Thumbnail der Datei test.gif

    Erklärung:
    Ich erstelle die Thumbnails mit einer festen Breite und einer dymanischen Höhe, denn ein Layout kann sich ohne Probleme nach unten anpassen, wohin gegen Breiten etwas problematischer sind. Die Breite wird in makethumbnail() bestimmt. Die einzig wirklich öffentliche Funktion ist thumbnail::show($origin, $path = ./); die überprüft ob ein Thumbnail (Prefix.Originalbildname) vorhanden ist oder das Originalbild neuer als das Thumbnail ist, falls ja wird dieses erstellt.
    Ich arbeite nur mit den drei gängigen Internetbildformaten jpg, gif und png!

    UPDATE: Die Klasse ist jetzt schleifenfreundlicher. Der Konstruktor kann vor einer möglichen Schleife aufgerufen werden, hier wird dann im Voraus das Prefix bestimmt und die Thumbnailbreite bestimmt.
    In der Schleife muss dann jedes Mal bestimmt werden wie die ORiginaldatei heißt und in welchem Ordner sie liegt.
     
  2. 29. Oktober 2006
    AW: Thumbnailklasse

    Nice, vllt. solltest du noch dazu schreiben das die gdlib benötigt wird um die Thumbnails zu erstellen.

    FlowFlo
     
  3. 29. Oktober 2006
    AW: Thumbnailklasse

    Jo, sollte ja eigentlich klar sein und da die gdlib ja standard bei php5 ist, hab ich das jetzt einfach weg gelassen.
     
  4. 29. Oktober 2006
    AW: Thumbnailklasse

    Die Class sieht eigentlich ganz gut aus bis auf ein paar Sachen.

    1. Wieso benutzt du === anstatt ==? (Z. 98, 102, 106)
    2. "$this->_ioriginaldate >= $this->_ithumbnaildate" -> "oder dieser älter als die Originaldate ist" >= wuerde auch ein neues Thumbnail generieren, wenn die Erstellzeit gleich ist.
    3. Error Handling. Fehlt komplett!
     
  5. 29. Oktober 2006
    AW: Thumbnailklasse

    1. Hi The Dude der Vergleichsoperator ==? ist mir vollkommen unbekannt, hab ich in meiner Laufbahn noch nie gesehen, nie benutzt noch nie gefunden! Ich überprüfe mit === nicht nur nach Wert sondern auch nach Typ, da ich eine starke Typisierung bevorzuge überprüfe ich halt nach Wert und Typ!
    2. Jo korrekt, ich gehe davon aus dass ein Thumbnail nach dem Originalfoto generiert wird, heißt also dass der Timestamp des Thumbnails größer sein muss, als der des Originalbilds. Somit ist das größer als schonmal gerechtfertig. Doch folgende Situation. Du lädst ein Bild hoch und läßt davon ein Thumbnail erstellen. Anschließend fällt dir auf dass du das falsche Originalbild hochgeladen hast, lädst ein neues hoch und nennst es gleich. Wenn jetzt der Timestamp der Erstellung beider Dateien (der neue Originaldatei und des alten Thumbnails) gleich ist, muss ja trotzdem ein neues Thumbnail her, nur bei "größer als" würde er das nicht tun! Da diese Klasse für ein Projekt ist, wo dieser Fall eintreten könnte ist es so sinnvoller! Zumal man dafür bestimmt auch andere Fälle finden könnte und ich finde mit dem Vergleichsoperator >= sind einfach mehr davon abgedeckt.
    3. Korrekt Errorhandling fehlt, die meisten Funktionen würden bei einem Fehler auch direkt einen fatalen PHP Error werfen, und den kann ich nicht fangen. filemtime() für das Thumbnail wird aller wahrscheinlichkeit einen Fehler werfen, da in den meisten Fällen noch kein Thumbnail vorhanden ist, weswegen ich den Fehler unterdrücke. Und der Rest ist für mich eindeutig, Server ist richtig eingestellt, Ordnerberechtigungen in meinem aktuellen Projekt stimmen, die Klasse wird von keiner Benutzereingabe erreicht, sondern nur Code von mir und damit mache ich mir um Fehler keine Sorgen, denn wenn kein Thumbnail vorhanden ist, wird ein rotes Kreuz zu Sehen sein und fertig.
    Mann kann halt bei Clean() für Usereingaben direkt überprüfen ob ein leerer String übergeben wurde, z.B. wenn der Aufruf der Thumbnail in einer Klasse vorkommt mit "automatisch" generierten Namen vorkommt oder bei der Funktion filemtime() ob die Originaldatei überhaupt vorhanden ist ... den Rest halte ich für unnötig!

    Probleme die ich hier höchstens noch sehe ist die Kompatibilität mit GIF, aber wenn hier eine inkompatible gdlib erwischt wurde, sollte man keine Gifs benutzen. PNGs sind mittlerweile sowieso sinnvoller.
     
  6. 29. Oktober 2006
    AW: Thumbnailklasse

    Ja, recht hast du schon. Ist halt das, was mir beim Betrachten aufgefallen ist. Gemeint war uebrigens nicht "==?" sondern "=="!
     
  7. 30. Oktober 2006
    AW: Thumbnailklasse

    Boing hehe, da hab ich wohl zu sehr in PHP gedacht. Jo hab ich dir ja gesagt warum ich "===" man hätte natürlich auch den "einfachen" Operator "==" nehmen können, aber so find ich das Ergebnis eindeutiger, der rückgabe wert der funktion is halt nicht boolean sondern integer und deswegen halt einfach auch die überprüfung nach typ.
     
  8. 6. November 2006
    AW: Thumbnailklasse

    UPDATE: Die Klasse ist jetzt schleifenfreundlicher. Der Konstruktor kann vor einer möglichen Schleife aufgerufen werden, hier wird dann im Voraus das Prefix bestimmt und die Thumbnailbreite bestimmt.
    In der Schleife muss dann jedes Mal bestimmt werden wie die ORiginaldatei heißt und in welchem Ordner sie liegt.
     
  9. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.