tutorials.de Buch-Aktion 05/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
NEIN
ANTWORTEN
16
ZUGRIFFE
2254
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Guten Abend!
    Ich habe ein kleines Problem. Ein Freund von mir brauchte eine Captcha Klasse für ein Forum. Ich habs versucht jedoch ohne viel Erfolg. Muss zudem gestehen, dass ich mich vorher nie mit den Imagefunktionen beschäftigt habe. Wäre nett wenn ihr mal über den Code schauen könntet und mir Fehler aufweisen könntet. Für ein Paar Tips zur Verbesserung bin ich natürlich auch offen. Ich suche jetzt schon seit zwei stunden und habe nichts richtiges gefunden. Wäre euch echt dankbar! Die Klasse sieht so aus:
    PHP-Code:
    <?php
    error_reporting
    (E_ALL);

    /* The Captcha class */
    class Captcha
    {    
        
    /*Captcha Variables*/
        
    protected $font_face;
        protected 
    $captcha_string;
        protected 
    $blanko_image;
        protected 
    $captcha_image;
        protected 
    $captcha_width 150;
        protected 
    $captcha_height 50;
        protected 
    $captcha_highlights 50;
        
        
    /**
        * Creates a string with letters and numbers
        * 
        * @name Captcha::create_string()
        * @access public
        * @return boolean
        */
        
    public function create_string()
        {
            
    $letters range('a','z');
            
    $numbers range(1,26);
            
    $captcha '';
            
            for (
    $i strlen($captcha); $i 3$i++) 
            {
                
    $rnum mt_rand(0,25);
                
    $captcha[] = $numbers[$rnum];
                unset(
    $rnum);
                
                
    $rlet mt_rand(0,25);
                
    $captcha[] = $letters[$rlet];
                unset(
    $rlet);
            }
            
            
    shuffle($captcha);
            
            for (
    $i 0$i count($captcha); $i++) 
            {
                
    $this->captcha_string .= $captcha[$i];
            }
            
            
    $_SESSION['captcha'] = $this->captcha_string;
            
            return 
    true;
        }
        
        
    /**
        * Creates a blanko-image for the captcha
        * 
        * @name Captcha::create_blanko_image()
        * @access public
        * @return boolean
        */
        
    public function create_blanko_image()
        {
            
    $font mt_rand(1,5);
            
    $this->font_face $font;
            
            
    $imgwidth = (strlen($this->captcha_string)*imagefontwidth($font)) + 10;
            
    $imgheight imagefontheight($font) + 10;
            
            if (
    $imgwidth $this->captcha_width) { $imgwidth $this->captcha_width; }
            if (
    $imgheight $this->captcha_height) { $imgheight $this->captcha_height; }
            
            
    $blanko_image imagecreate($imgwidth$imgheight); 
            
    $this->blanko_image $blanko_image;
            
            return 
    true;
        }
        
        
    /**
        * Fills the blanko-image for the captcha
        * 
        * @name Captcha::fill_blanko_image()
        * @access public
        * @return boolean
        */
        
    public function fill_blanko_image()
        {
            for (
    $i 0$i $this->captcha_highlights$i++) 
            {
                
    $colors[] = imagecolorallocate($this->blanko_imagemt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
            }
            
            for (
    $i 0$i $this->captcha_highlights$i++) 
            {
                
    imagerectangle($this->blanko_imagemt_rand(0,$this->captcha_width),mt_rand(0,$this->captcha_height),mt_rand(0,$this->captcha_width),mt_rand(0,$this->captcha_height), $colors[$i]);
                
    imageline($this->blanko_imagemt_rand(0,$this->captcha_width),mt_rand(0,$this->captcha_height),mt_rand(0,$this->captcha_width),mt_rand(0,$this->captcha_height), $colors[$i]);
            }
            
            
    $captcha_image imagestring($this->blanko_image,$this->font_face,10,10,$this->captcha_string,$colors[mt_rand(0,$this->captcha_highlights)]);
            
    $this->captcha_image $captcha_image;
            
            return 
    true;
        }
        
        
    /**
        * Shows the finished captcha
        * 
        * @name Captcha::show_captcha()
        * @access public
        * @return boolean
        */
        
    public function show_captcha()
        {    
            
            
    header("content-type: image/gif");
            
            
    $this->create_string();
            
    $this->create_blanko_image();
            
    $this->fill_blanko_image();

            
    imagegif($this->captcha_image);
            
    imagedestroy($this->captcha_image);
            
            return 
    true;
        }
    }

    ?>
    Der Aufruf dieser Klasse sieht so aus:
    PHP-Code:
    <?php
        
    include ('Captcha.php');
        
    $cap = new Captcha();
        
    $cap->show_captcha();
    ?>
    MfG, Andy
     

  2. #2
    Tyg3r Tyg3r ist offline Mitglied Gold
    Registriert seit
    Sep 2007
    Beiträge
    216
    Hi,
    öhm was tut denn nicht?

    Wenn ich was verbessern würde, dann höchstens etwas ideologisches
    Also ich würde eine rein statische Klasse schreiben.
    Finde den Code "schöner" und kleine Vorteile sind:
    - Es werden weniger Resourcen beansprucht, da keine Instanz erzeugt wird.
    - Es muß beim "Aufruf" nicht instanziert werden.

    Auch bin ich bei Namensgebung pingelig (Das hast Du nun davon, wenn Du nach "Tips" frägst )
    Bei mir würde der Aufruf demnach so aussehen:

    PHP-Code:
    <?php
        
    include ('Captcha.php'); // *
        
    Captcha::run(); // **
    ?>
    *) Den Include kann man übrigens seit PHP5 automatisieren (grade bei größeren Projekten sehr zu empfehlen):
    http://www.php.net/manual/de/function.spl-autoload.php

    **) "einfacher und sparsamer", dadurch, dass noch weitere Methoden der Klasse aufgerufen werden, entsteht ein Ablauf, welchen ich persönlich mit "run" definiere. "show" wäre eine selbstständige Methode dieser Klasse. Ok, jetzt reicht es, sonst werde ich noch zu abstrakt

    Aber nun zum Problem, einfach mal schildern, dann wissen wir "wo suchen".

    Gruß tyg3r
    Geändert von Tyg3r (03.10.07 um 02:07 Uhr)
     

  3. #3
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Guten Morgen!

    Ich weiß leider selber nicht, was bzw. welcher Bereich nicht richtig funktioniert. Ich erhalte nur folgende Fehlermeldung:
    Code :
    1
    
    Die Grafik "http://www.puk.de/redway/captcha/captchatest.php" kann nicht angezeigt werden, weil sie Fehler enthält.
    Dürfte dich auch nicht richtig weiter bringen. Oder?

    Was verstehst du unter rein statischer Klasse? Oder verstehst du darunter das alle Methoden statisch sind, nur Konstanten verwendet werden und sich eine Methode auf die Klasse als solches bezieht?
    Oder sollen die Farben festgelegt sein. Also nicht per zufallsprinzip gewählt werden? Wäre nett wenn du ein Beispiel bringen könntest.

    Den link sehe ich mir mal an und werde dann das Script demnach ändern.

    Hätte dann aber noch eine Frage. Und zwar wie kann ich die Buchstaben und Ziffern, die ich in das Captcha eintrage rotieren? Und wie bekomme ich im Hintergrund diesen Rauscheffekt hin, den viele Captchas verwenden?

    MfG, Andy
     

  4. #4
    Registriert seit
    Dec 2002
    Ort
    Trier
    Beiträge
    17.502
    Blog-Einträge
    10
    Verwende mal als Inhaltstyp „text/plain“ um mögliche Fehlermeldungen lesen zu können.
     
    Markus Wulftange

  5. #5
    Registriert seit
    Mar 2002
    Ort
    Stuttgart (Baden-Württemberg)
    Beiträge
    984
    Blog-Einträge
    7
    Für das Rauschen ist es am besten, ein paar Hintegründe in Photoshop, Gimp oder dem Grafikprogramm deiner Wahl zu erstellen und dann per imagecreatefromjpeg() oder ähnlicher Funktion zu laden, da sonst viel Rechenleistung verschwendet wird, wenn du sie von PHP on the fly generieren lässt.
     
    Gruß mAu


    ──────────────────────────
    Ich auf flickr

    * Unformatierten Quellcode schaue ich mir _nicht_ an!
    * Sollte ich euch bei einer Frage weitergeholfen haben, würde ich mich über eine positive Bewertung freuen.
    * Bitte die Netiquette beachten.
    * Vergesst nicht, beantwortete Fragen als erledigt zu markieren!


  6. #6
    Avatar von Flex
    Flex Flex ist offline (aka Felix Jacobi)
    tutorials.de Moderator
    Registriert seit
    Nov 2001
    Ort
    Wuppertal
    Beiträge
    5.295
    Blog-Einträge
    65
     
    KIDS Kinderbetreuungsdienst
    Xing

    "When you play the game of thrones, you win or you die. There is no middle ground."
    by Cersei Lannister in "A Game Of Thrones"

  7. #7
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Morgen!
    Also wenn ich, wie von Gumbo vorgeschlagen den Header ändere erhalte ich folgende Fehlermeldungen:
    Code :
    1
    2
    3
    4
    5
    
    Warning: Cannot modify header information - headers already sent by (output started at /home/redway/www/captcha/Captcha.php:2) in /home/redway/www/captcha/Captcha.php on line 129
     
    Warning: imagegif(): supplied argument is not a valid Image resource in /home/redway/www/captcha/Captcha.php on line 135
     
    Warning: imagedestroy(): supplied argument is not a valid Image resource in /home/redway/www/captcha/Captcha.php on line 136
    Die Klasse von Felix Jakobi hilft mir nur bedingt weiter, denn dann müsste ich ja noch eine weitere klasse Programmieren, die diese nutzt um dann ein Captcha zu erstellen. Jedoch ist dort die Idee von Font-color garnicht so schlecht.

    Nach dem Punkt "Buchstaben rotieren" habe ich nochmal selbst gesucht jedoch nichts gefunden. kann mir da jemand helfen?

    Änder gerade nochmal die Klasse. Stell sie dann heute abend nochmal in der neuen Version rein.

    MfG, Andy
     

  8. #8
    Registriert seit
    Mar 2002
    Ort
    Stuttgart (Baden-Württemberg)
    Beiträge
    984
    Blog-Einträge
    7
    Die imagestring()-Funktion gibt entweder true oder false zurück. Deswegen musst du in der Captcha::showCaptcha()-Funktion folgendes ändern:
    PHP-Code:
            imagegif($this->blanko_image);
            
    imagedestroy($this->blanko_image); 
     
    Gruß mAu


    ──────────────────────────
    Ich auf flickr

    * Unformatierten Quellcode schaue ich mir _nicht_ an!
    * Sollte ich euch bei einer Frage weitergeholfen haben, würde ich mich über eine positive Bewertung freuen.
    * Bitte die Netiquette beachten.
    * Vergesst nicht, beantwortete Fragen als erledigt zu markieren!


  9. #9
    Tyg3r Tyg3r ist offline Mitglied Gold
    Registriert seit
    Sep 2007
    Beiträge
    216
    Hi,

    PHP-Code:
    <?php
    error_reporting
    (E_ALL);

    /* The Captcha class */
    class Captcha
    {    
        
    /* public vars */
        
    public static $length 6;
        
        
    /* private vars */
        
    private static $font;
        private static 
    $width 150;
        private static 
    $height 50;
        private static 
    $highlights 50;
        
        
    /**
        * Run captcha application
        * 
        * @name Captcha::run()
        * @access public
        * @return boolean
        */
        
    public static function run(){    

            
    header("content-type: image/gif");

            
    $str self::create_string();
            
    $img self::create_blanko_image($str);
            
    $img self::fill_blanko_image($img$str);

            
    imagegif($img);
            
    imagedestroy($img);

            return 
    true;
        }
        
        
    /**
        * Creates a string with letters and numbers
        * 
        * @name Captcha::create_string()
        * @access private
        * @return string
        */
        
    private static function create_string(){

            
    $chars array_merge(
                            
    range('0''9'), 
                            
    range('a''z')
                        );
            
    mt_srand((double)microtime()*1000000);
            for (
    $i 1$i <= (count($chars)*2); $i++){
                
    $_key mt_rand(0,count($chars)-1);
                
    $_tmp $chars[$_key];
                
    $chars[$_key] = $chars[0];
                
    $chars[0] = $_tmp;
            }
            return 
    substr(implode('',$chars),0,self::$length);
        }
        
        
    /**
        * Creates a blanko-image for the captcha
        * 
        * @name Captcha::create_blanko_image()
        * @access private
        * @param String $str
        * @return img object
        */
        
    private static function create_blanko_image($str){

            
    self::$font mt_rand(1,5);

            
    $imgwidth = (strlen($str)*imagefontwidth(self::$font)) + 10;
            
    $imgheight imagefontheight(self::$font) + 10;

            if (
    $imgwidth self::$width
                
    $imgwidth self::$width;
            if (
    $imgheight self::$height
                
    $imgheight self::$height;

            return 
    imagecreate($imgwidth$imgheight);
        }
        
        
    /**
        * Fills the blanko-image for the captcha
        * 
        * @name Captcha::fill_blanko_image()
        * @access private static
        * @param img object $img
        * @param String $str
        * @return img object
        */
        
    private static function fill_blanko_image($img$str){

            for (
    $i 0$i self::$highlights$i++) {
                
    $colors[] = imagecolorallocate($imgmt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
            }

            for (
    $i 0$i self::$highlights$i++) {
                
    imagerectangle($imgmt_rand(0,self::$width),mt_rand(0,self::$height),mt_rand(0,self::$width),mt_rand(0,self::$height), $colors[$i]);
                
    imageline($imgmt_rand(0,self::$width),mt_rand(0,self::$height),mt_rand(0,self::$width),mt_rand(0,self::$height), $colors[$i]);
            }
            
            return 
    imagestring($img,self::$font,10,10,$str,$colors[mt_rand(0,self::$highlights)]);
        }
        
    }

    ?>
    Das verstehe ich unter statisch, also Methoden und Variablen statisch.

    Der Aufruf wäre dann wie folgt möglich:
    PHP-Code:
    <?php
        
    include ('Captcha.php');
        
    Captcha::$length 10;
        
    Captcha::run();
    ?>
    Ist halt stark Geschmackssache =)
    Mir gefällt es so besser. In den meisten Fällen benötigt man keine Objekte der Klassen.

    Wegen dem Fehler, versuch doch mal das Blanco auszugeben:

    PHP-Code:
    <?php
        $img 
    self::create_blanko_image($str);
        
    imagegif($img);
    ?>
    Gruß tyg3r
     

  10. #10
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Hallo!

    Danke nochmal für eure tollen Tipps und Anregungen. Ich werde das in meine Klasse einbauen und einiges nochmal ändern. Ich poste dann die fertige Klasse heute Abend nochmal hier im Forum, da ich jetzt erstma weg muss.

    MfG, Andy
     

  11. #11
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Guten Morgen!

    Es ist vollbracht! Die Captcha-Klasse ist fertig geschrieben. Das Ergebnis kann hier betrachtet werden.

    Ich möchte anmerken, dass für dieses Captcha keine Bilder verwendet werden. Alles wird automatisch generiert, auch der Farbverlauf im Hintergrund.

    Ich habe nur ein Problem. Es kann irgendwie nach dem Aufruf der Klasse keine Ausgabe mehr gemacht werden. Wieso?
    PHP-Code:
    <?php
        
    include ('Captcha.php');
        
    Captcha::run();
        echo 
    'Inhalt Captcha-SESSION: '.$_SESSION['captcha'];
    ?>
    MfG, Andy
    Geändert von Avedo (04.10.07 um 16:46 Uhr)
     

  12. #12
    Avatar von maeTimmae
    maeTimmae maeTimmae ist offline Mitglied Platin
    Registriert seit
    Aug 2007
    Ort
    Erfurt, Saarbrücken, Leipzig und Fulda
    Beiträge
    515
    Nun schon 2.5 Tage her, aber ich möchte dir dennoch gerne antworten:

    PHP-Code:
    public static function run(){
        
    header("content-type: image/gif");
        
    // ...

    Lass dir mal den "Quelltext" der Ausgabe darstellen - Dort solltest du dann den String "Inhalt Captcha-SESSION: SID" zu sehen bekommen - Der Browser verarbeitet jedoch während des Rendering-Prozesses den gesendeten Inhaltstyp, der in deinem Fall Image/Gif ist, und demnach stellt der Browser auch einfach eine Grafik vom Typ Gif dar. Dass die Zeichen des Strings nicht verarbeitet werden, liegt daran, dass diese nur scheinbar nicht verarbeitet werden - Sie liegen außerhalb der Bildausmaße und werden somit nicht für die sichtbare Grafik verarbeitet. Das ist übrigens auch nützlich, wenn man Archive und Bilddaten zu einer Masse vermengen möchte um zB Daten zu verstecken
     

  13. #13
    Avatar von Avedo
    Avedo Avedo ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Göttingen
    Beiträge
    387
    Hallo!
    Es ist schwer sich den Seitenquelltext ausgeben zu lassen wenn der Contenttype - image/gif ist. Kannste ja mal bei meinem Beispiellink versuchen.

    Wie muss ich das ganze denn jetzt ändern, damit ich das ganze zum Beispiel in eine Seite mit einem Formular einbauen kann, ohne dass die Seite und das Formular versteckt werden? Kann ich da einen allgemeineren Contenttype wählen?

    Wäre dir für deine Antwort sehr dankbar.
    MfG, Andy
     

  14. #14
    Registriert seit
    Mar 2002
    Ort
    Stuttgart (Baden-Württemberg)
    Beiträge
    984
    Blog-Einträge
    7
    Du musst eine Datei erstellen, die sich nur um die Ausgabe des Captchas kümmert. Diese kannst du dann mit einem normalen img-Tag ansprechen und das Captcha wird ausgegeben.
    PHP-Code:
    // captcha.php
        
    include ('Captcha.php');
        
    Captcha::run(); 
    Code html4strict:
    1
    2
    3
    4
    5
    
    // formular.php
    <form action="formular.php" method="post">
    <img src="captcha.php" alt="Captcha"> <input type="text" value="">
    <input type="submit" name="send">
    </form>
     
    Gruß mAu


    ──────────────────────────
    Ich auf flickr

    * Unformatierten Quellcode schaue ich mir _nicht_ an!
    * Sollte ich euch bei einer Frage weitergeholfen haben, würde ich mich über eine positive Bewertung freuen.
    * Bitte die Netiquette beachten.
    * Vergesst nicht, beantwortete Fragen als erledigt zu markieren!


  15. #15
    Avatar von maeTimmae
    maeTimmae maeTimmae ist offline Mitglied Platin
    Registriert seit
    Aug 2007
    Ort
    Erfurt, Saarbrücken, Leipzig und Fulda
    Beiträge
    515
    Zitat Zitat von Catull Beitrag anzeigen
    Es ist schwer sich den Seitenquelltext ausgeben zu lassen wenn der Contenttype - image/gif ist. Kannste ja mal bei meinem Beispiellink versuchen.
    Unmöglich ist es aber nicht - zB mit dem Firefox Bon Echo, der mir das hier ausspuckt:
    Code :
    1
    2
    3
    
    GIF87aK��„��trt<:<¬ª¬ŒŽŒTVT|~|DFDœšœdbd,*,tvt<><¼Òì”’”\Z\$"$„†„LNL¤¢¤ljl424���������������������,����K���þ $Ždižhª®*à¾p,Ï®€5t®ÓWß‹ pH,‡6Æq9¼à�O_(bX¯X…D‚íz½Á—!-_ €ñXdh&møv«pÃßñ8âîfÂfn‚ƒ„…‚"‰Š‰s‹{‹a”—˜˜"œsžž’£ž¨®¯°"«µ ¡·¶’´¿¿¶¶¿´´Ãȷ˼¼³a6a¡&дÐ%6ÑÙ߬Ѭ    ÆååÒ"ðññsï’ïö"ûðôùƒ¯ <î)D�Ð ˆ
    ’@<1¢I-BÀ·1BECF‹ˆÐþSj¬À²ÂÖ/²l�‚K›"´¬ÉòeO›" ¼I èΣ;EXºTi8’pêÒjB`ê´€,DXø%¢hѬLÓr…Р Ìuê;%@Õ˶J%àK€Ba]ºD(X¬àÀ⋌8P ¤âËç<ª�ób„˜%0q!€éÓŒS?†pAAëHøp×eÖ¤c³¾€—åÖÿê0œ¸ƒ²X¹nÝcùrÒ¦AœzñÇ!L×^štëÛ‰›&qz»„ìÚ    ”¶aº´{ñ"jˆw>öɇwO½Ø’ÅE_mèeG`\aÔ·§`và ƒ§•&Þ{<(~Fð Bvh!J`Ÿƒ
    Zhƒ‡Ð•GÁŠ,¶è¢‹ø9°bI/ÖÈ¢ 6Úh�re�)dfi$ÄE䑹$“PFYTüÁ•Xf©å–X&`–Jr)æ˜d^é†�& æšlªA›l"çœnÎù¦t²é‡X”T’—éøéå J¨œ†J( Ð衈.Z¨;²`饘fZB�;[b]Inhalt Captcha-SESSION: xSK30y[/b]

    Zitat Zitat von Catull Beitrag anzeigen
    Wie muss ich das ganze denn jetzt ändern, damit ich das ganze zum Beispiel in eine Seite mit einem Formular einbauen kann, ohne dass die Seite und das Formular versteckt werden? Kann ich da einen allgemeineren Contenttype wählen?
    mAu hat es bereits gesagt - Einbinden kannst du das über einen weiteren Aufruf in einem HTML-Dokument. Wie aber kannst du nun das Captcha überprüfen? Meistens wählt man den Umweg über eine Datenbank, in der für x Sekunden eine Captcha Zeichenkette mit einem Identifikator (zB Session-ID) gespeichert wird. Diese SID wird nun verwendet um über den gesamten Prozess der Aufrufe die gleiche Captcha-Zeichenkette benutzen zu können. In sofern würde ich deine Captcha::run() erweitern um ein Captcha::run($string). $string erhälst du aus der Datenbank, aus der du mit der SID als Index eben diesen ausliest und verwertest. Nach der Eingabe überprüfst du dann, ob $_POST['captchainput'] auch mit dem Eintrag des Captchastring in der DB übereinstimmt.
     

Ähnliche Themen

  1. Mit einer Klasse Objekte für eine andere Klasse erstellen.
    Von New2Java im Forum Java Grundlagen
    Antworten: 14
    Letzter Beitrag: 21.11.10, 12:37
  2. Member-Variable einer MFC-Klasse in einfache Klasse einfügen
    Von cappa555 im Forum VisualStudio & MFC
    Antworten: 1
    Letzter Beitrag: 12.12.08, 17:33
  3. Problem mit Captcha Klasse
    Von ne0hype im Forum PHP
    Antworten: 5
    Letzter Beitrag: 25.05.08, 16:27
  4. [JSP] Captcha
    Von SeeSharpNewBee im Forum Enterprise Java (JEE, J2EE, Spring & Co.)
    Antworten: 0
    Letzter Beitrag: 13.02.08, 14:26
  5. Antworten: 2
    Letzter Beitrag: 02.01.07, 16:27