C'est quoi ?

Le captcha est la petite image que l'on voit de plus en plus sur les formulaires. Celle que vous devez recopier et qui censément empeche un robot de s'inscrire ou de poster.
ex:
Sur cette page, vous trouverez un classe qui vous permet de générer un Captcha.
Je l'accompagne d'un exemple pour mieu comprendre comment l'utliser.

Telecharger les sources

captcha.zip Source complete, avec la police
Ce zip contient 4 fichiers :

  • test.php est la page avec le formulaire, pour vous montrer comment afficher et vérifier le captcha
  • ShowCaptcha.php, Génére et affiche l'image captcha et stocke la chaine en session
  • captcha.class.php la classe qui est appelée par le fichier précédent et qui fait tout le travail d'image.
  • BRAD.TTF, une police pas mal pour un cpatcha.

brad.zip Uniquement la police

Le principe

Un fichier php, va appeler la classe qui génére le captcha, stocker la chaine généré dans une variable de session et afficher l'image généré. Un autre page va appellé la page précédente pour afficher l'image dans le formulaire et faire le vérification de saisie en fonction de la variable de session.

Code

Commencons par la classe

php
<?php
 
  /******************************************************************
  CAPTCHA Class,
  Adaptation d'un classe de Pascal Rehfeldt <Pascal@Pascal-Rehfeldt.com>
  sous license GNU GPL
  Adapter par iDo.
  Utilisation, 
  Lors de l'instantiation de la classe les paramtres a fournir sont :
     *   La taile du captcha (6 par defaut)
     *   Le type d'image (png par defaut)
     *   Les lettres (si vide, elle sont tiré au hasard)
     *   La police (ARIAL.TFF par defaut)
     *   La taille de police (19 par defaut)
  L'image est automatique renvoyé vers le navigateur.
  L'appel de la procédure $captcha->GetCaptchaString(); permet de stocker en variable la chaine généré aléatoirement.	 
 
   * GNU General Public License (Version 2, June 1991)
   *
   * This program is free software; you can redistribute
   * it and/or modify it under the terms of the GNU
   * General Public License as published by the Free
   * Software Foundation; either version 2 of the License,
   * or (at your option) any later version.
   *
   * This program is distributed in the hope that it will
   * be useful, but WITHOUT ANY WARRANTY; without even the
   * implied warranty of MERCHANTABILITY or FITNESS FOR A
   * PARTICULAR PURPOSE. See the GNU General Public License
   * for more details.
  ******************************************************************/
 
class captcha {
    var $Length;
    var $CaptchaString;
    var $ImageType;
    var $Font;
    var $CharSize;
 
    function captcha ($length = 6, $type = 'png', $letter = '',$font="ARIAL.TTF",$CharSize=19) {
      $this->Length    = $length;
      $this->ImageType = $type;
      $this->Font      = $font;
      $this->CharSize = $CharSize;
      if ($letter == '') {
        $this->StringGen();
      } else {
        $this->Length        = strlen($letter);
        $this->CaptchaString = $letter;
      }
 
      $this->MakeCaptcha();
	  $this->SendHeader();
	  $this->ShowImage();
    }
 
    function StringGen () {
		$CharPool = array ('Z','I','J','L','O','S','V','A','B','C','D','E','F','G','H','K','M','N','P','Q','R','T','W','U','Y');
		$PoolLength = count($CharPool) - 1;
 
		for ($i = 0; $i < $this->Length; $i++) {
			$this->CaptchaString .= $CharPool[mt_rand(0, $PoolLength)];
		}
    }
    function MakeCaptcha () {
		$dimensions = imagettfbbox($this->CharSize, -4, $this->Font, $this->CaptchaString);
		$imageheight = $dimensions[1] - $dimensions[7] + 10;
		$imagelength = $dimensions[2] - $dimensions[0] + 5;
 
		$image       = imagecreate($imagelength, $imageheight);
		$bgcolor     = imagecolorallocate($image, 222, 222, 222);
		$stringcolor = imagecolorallocate($image, 0, 0, 0);
		$linecolor   = imagecolorallocate($image, 0, 0, 0);
 
		imagettftext($image, $this->CharSize, -4, 5, $this->CharSize + 5,
                   $stringcolor,
                   $this->Font,
                   $this->CaptchaString);
		$this->image=$image;
	}
 
	function SendHeader () {
      switch ($this->ImageType) {
        case 'jpeg': header('Content-type: image/jpeg'); break;
        case 'png':  header('Content-type: image/png');  break;
        default:     header('Content-type: image/png');  break;
      }
    }
 
	Function ShowImage() {
		switch ($this->ImageType) {
			case 'jpeg': imagejpeg($this->image); break;
			case 'png':  imagepng($this->image);  break;
			default:     imagepng($this->image);  break;
		}
	}
    function GetCaptchaString () {
      return $this->CaptchaString;
    }
}
 
?>

Cette classe, lors de son instanciation, va généré et envoyé vers le naviguateur l'image du captcha.
Le chaine de caractere généré reste accessible via la fonction GetCaptchaString();

ShowCaptcha.php

php
<?php
  session_start();
  //Charge la classe
  require('captcha.class.php');
 
  //Crée le CaptCha
				       //Longueur,Format,Jeu de lettre,Police,Taille
  $captcha = new captcha(5,'png','','BRAD.TTF',19);
 
  //Enregistre la chaine de caractere dans une variable session
  $_SESSION['CAPTCHA']=$captcha->GetCaptchaString();
 
?>

Cette page est très courte. Elle démarre une session , charge la classe, l'instancie (ce qui va avoir pour effet de faire croire au navigateur que cette page est du type d'une image (la classe modifie les header dans ce but). Après ça, le captcha est affiché et la chaine sauvé dans une variable de session.

Lorsque vous instancier la classe, vous lui passez en paramètre une police TTF. Assurez vous que cette police soit sur le serveur, dans le même dossier que cette page !!!!
Sur certaine config, il faut passer le chemin complet vers la police et non pas simplement le nom.
Exemple : /home/page/www/BRAD.TTF

Le test

php
<?php
	session_start();
 
if (@$_POST['action']!='') {
	if (strtolower($_POST['captcha']) == strtolower($_SESSION['CAPTCHA']))
		echo "Captcha recopié correctement<br />";
	else
		echo "Captcha mal recopié<br />";
}
//On affiche l'image : 
?>
Nouvelle image :<br />
<img src="captcha.class/ShowCaptCha.php" alt="captcha" />
<form action="" method="POST" name="captchaform">
<input type="text" value="" name="captcha" />
<input type="hidden" value="clic" name="action" />
<input type="submit" value="Ok" name="btn" />
</form>

Ici rien de bien compliqué. Pour afficher l'image, vous remarquez que l'ont fait appelle non pas a une image au sens fichier du terme mais a la page php, qui avec les header modifié sera considéré comme une image.