Un modulo protetto da un’immagine captcha! (PHP + GD)
Mi è capitato oggi di ricevere la richiesta di aiuto da parte di un amico che desiderava un modulo per l’invio di emails protetto da un codice captcha, in un primo momento non sapevo cosa fosse, ma dopo una googleata ho capito che per immagine captcha si intendono quelle immagini composte da alcuni caratteri non allineati ed uno sfondo che ne disturba il riconoscimento di modo da rendere difficile la vita ai BOT che incessantemente cercano il modo per rendere aumatico l’invio. I codici captcha infatti, se ben strutturati, sono riconoscibili solamente dall’occhio umano, estendendo questo attributo all’intero script.
Ma vediamo come possiamo realizzare una simile struttura, creeremo 2 diversi files, il primo conterrà il generatore dell’immagine, il secondo il codice di verifica e il form di invio:
Primo file: il generatore dell’immagine
Questo file creerà un dato di sessione, che ho chiamato “captcha_text”, che corrisponderà alla successione dei caratteri visualizzati nell’immagine.
<?php
#Comunichiamo al browser che o' che visualizzera' questo file sara' un'immagine, è necessario che il file non dia altro output oltre al contenuto dell'immagine, quindi facciamo molta attenzione ad eventuali spazi prima e dopo i tags php!
header("Content-type: image/png");
#Creiamo un'immagine alta larga 100px ed alta 50px
$im = imagecreate(100, 50);
#Impostiamo il colore di sfondo a nero (#000000), per convenzione il primo colore dichiarato e' quello dello sfondo
$background_color = imagecolorallocate($im, 0, 0, 0);
#Impostiamo anche un colore che sara' quello del testo
$text_color = imagecolorallocate($im, 233, 14, 91);
#Diamo inizio ad un ciclo "for", che generera' una successione di 30 numeri, la dichiarazione .= significa che cio' che segue andra' a finire dopo l'attuale contenuto della variabile "$randstr"
for($i=0;$i<30;$i++)
$randstr.=rand(0,9);
#Generiamo l'hash della stringa ottenuta con il ciclo precedente
$randstr=md5($randstr);
#Diminuiamo la lunghezza della stringa (attualmente lunga 30 caratteri), ora la stringa sara' lunga 5 caratteri a partire dal primo
$randstr=substr($randstr, 0, 5);
#Trasformiamo i caratteri minuscoli in caratteri maiuscoli, per rendere piu' comprensibile l'immagine
$randstr=strtoupper($randstr);
#Ora "sminuzziamo" la stringa, in modo da ottenere un array composto da 5 elementi: i 5 caratteri della stringa
$chars=str_split($randstr);
#Tramite 5 cicli i caratteri saranno posizionati in giro per l'immagine, con un offset di +/-2 pixel, sia in X che in Y, ogni carattere distera' da quello successivo di circa 15 pixel
for($i=0;$i<5;$i++)
imagechar($im, 5, 10+15*$i+rand(-2, +2), 15+rand(-2, +2), $chars[$i], $text_color);
#Con altri 5 cicli disturberemo lo sfondo, con altrettante rette che attraverseranno l'immagine partendo da due cordinate casuali ed arrivando ad altre due cordinate casuali
for($i=0;$i<5; $i++)
imageline($im, rand(0,100), rand(0,50), rand(0,100), rand(0,50), $text_color);
Diamo in output la nostra creazione
imagepng($im);
##Eliminiamo i dati temporanei relativi all'immagine dopo averla visualizzata
imagedestroy($im);
#Richiamiamo la sessione (un passaggio obbligatorio se vogliamo dichiarare delle variabili di sessione)
session_start();
#Attribuiamo alla variabile di sessione "captcha_text" il valore $randstr, ovvero la stringa composta da 5 caratteri generata qualche linea piu' su
$_SESSION['captcha_text']=$randstr;
#Chiudiamo i tags del php
?>
Secondo file: un form dove inserire il codice captcha (captcha.php)
Questo file conterrà i dati che si vogliono inviare e la conferma del nostro codice captcha, sarà quindi necessario richiamare l’immagine del codice, ecco come si presenterà il nostro file:
<?
#Controlliamo che esista il dato "submitted_code", che sarà impostato solamente se è già stato digitato il codice captcha e controlliamo
if((isset($_POST['submitted_code']))&&($_POST['submitted_code']==$_SESSION['captcha_text']))
{
#Facciamo partire la sessione, questo passaggio è obbligatorio per leggerne i dati e le veriabili
session_start();
#Output ed operazioni legate alla corretta digitazione del codice (es. mandare un'email, eseguire un'operazione sul database...)
echo "Messaggio di OK";
}
#Altrimenti riproponiamo l'inserimento del codice
else
{
?>
<form name="form1" method="post" action="#">
<p>
<input type="text" name="campoacaso">Un campo a caso<br>
</p>
<p>
<input name="verify_code" type="text" id="vcode">Copia il codice sottostante nel box<br>
<img src="captcha.php" width="100" height="50"><br>
<input type="submit" name="Submit" value="Invia">
</p>
</form>
<? }
?>