Videos d’introducció a Android de “Esto es Google” de Google Mexico.

Uns vídeos d’introducció a Android de la devfest “Esto es Google” de Google Mèxic.

“Android SDK: Qué es y cuáles son las últimas novedades.”

“Construcción de aplicaciones de Alto Rendimiento para Android”

“Taller: Android para principiantes.”

CURL. La navalla suïssa per a les transferències a Internet

En un post anterior vam presentar el ”truc” de com descarregar un lloc web fent servir el programa wget.

Doncs bé, curl (http://curl.haxx.se/) és un programa escrit per Daniel Stenberg similar a wget, i és del que parlarem en aquest post. Hi han algunes diferències entre curl i wget. Un bon resum el tenim en aquesta taula comparativa entre curl, wget i altres programes similars.

Aquest pdf és una presentació que ens pot fer donar una idea ràpida de curl.

Potser el més destacable és que curl es pot trobar també com a llibreria (libcurl), de forma que es pot enllaçar amb els nostres programes.

I no només C. curl es troba integrat a PHP. També hi ha un port per a Python. De fet, hi han ports per a un munt d’altres llenguatges.

Pel que fa estrictament al programa, curl pot tractar amb més protocols que wget , és capaç de fer uploads, autenticar-se i treballar amb cookies. Curl es pot integrar a scripts de shell de forma més “natural” que wget al ser una aplicació que funciona a l’estil Unix. Per exemple, fent ús de pipes que wget no admet.

Per contra, el súper-poder de wget és que és capaç de descarregar webs recursívament i aquest és, en veritat us dic, un gran súper-poder.

En general es considera que wget és una eina més útil per a descarregar llocs web, mentre que curl permet tractar amb llocs web a més baix nivell, que hagin de tenir en compte cookies, autenticació i enviaments de client a servidor.

La pàgina del manual de Curl és la referència imprescindible de l’aplicació.

Com ens baixaríem el manual amb curl? Fent:

curl -o manpage.html http://curl.haxx.se/docs/manpage.html 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current 
                                 Dload  Upload   Total   Spent    Left  Speed 
100  121k  100  121k    0     0   255k      0 --:--:-- --:--:-- --:--:--  308k

(amb l’opció -o per output, indica el fitxer de sortida)

Hi han més de 100 opcions diferents per a curl. Vet aquí les opcions d’emergència de Curl:

curl http://curl.haxx.se/ -o guarda-ho_aquí
curl ftp://curl.haxx.se/ -o guarda-ho_aquí
curl https://curl.haxx.se/ -o guarda-ho_aquí
curl sftp://curl.haxx.se/ -u elmeulogin:elmeupassword -o guarda-ho_aquí
curl scp://curl.haxx.se/ -o guarda-ho_aquí
curl tftp://curl.haxx.se/ -o guarda-ho_aquí
curl -T fitxer_upload ftp://curl.haxx.se/guarda-ho_aquí/
curl -T fitxer_upload https://curl.haxx.se/guarda-ho_aquí/

Aquesta altre pàgina http://www.cs.sunysb.edu/documentation/curl/ ens dona una excel·lent referència de la majoria de les opcions de curl, i amb exemples.

Com que la millor forma d’aprendre és practicant, ara faré alguns experiments en localhost. Primer de tot engego la meva versió local del XAMPP, de forma que tinc un servidor web amb PHP i un servidor d’FTP per a fer les proves.

Creo una carpeta curl dins htdocs i allà hi posaré els diferents html i php que aniré fent.

Emplenar un formulari web tipus POST amb CURL

Vet aquí el formulari

<html>
<head>
<title>Formulari de prova</title>
</head>
<body>
<form action="action.php" method="post">
Nom: <input type="text" name="sNom" /><br />
Valor: <input type="text" name="sValor" /><br />
Codi: <input type="text" name="sCodi" /><br />
<input type="submit" value="envia" /> <input type="reset" value="cancel·la" />
</form>
</body>
</html>

i la seva pàgina de resposta (action.php)

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Pàgina de resposta del formulari</title>
</head>
<body>
Valors enviats al formulari<br /><br />
sNom: <?php echo($_POST['sNom']) ?> <br />
sValor: <?php echo($_POST['sValor']) ?> <br />
sCodi: <?php echo($_POST['sCodi']) ?> <br />
</body>
</html>

Doncs bé, podem invocar per línia de comandes fent

albert@athena:~/lampp/htdocs/curl$ curl http://localhost/curl/action.php -FsNom=ALBERT -FsValor=1234546 -FsCodi=id > file.txt 

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current 
                                 Dload  Upload   Total   Spent    Left  Speed 
100   705  100   362  100   343  13730  13009 --:--:-- --:--:-- --:--:-- 20111

i el resultat és el fitxer de text file.txt que conté

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Pàgina de resposta del formulari</title>
</head>
<body>
Valors enviats al formulari<br /><br />
sNom: ALBERT <br />
sValor: 1234546 <br />
sCodi: id <br />
</body>
</html>

És dir, estic invocant el formulari des de línia de comandes, en un script, i el resultat és un fitxer de text que puc analitzar en el mateix script.

Pujar un fitxer a un servidor web (multipart)

El formulari de prova podria ser aquest. Comentar l’enctype al form i l’us del input type file

<html>
<head>
<title>Formulari de prova</title>
</head>
<body>
<form action="action-upload.php" method="post" enctype="multipart/form-data">
Nom: <input type="text" name="sNom" /><br />
Valor: <input type="text" name="sValor" /><br />
Codi: <input type="text" name="sCodi" /><br />
Fitxer: <input type="file" value="Upload" name="sUpload" /><br />
<input type="submit" value="envia" /> <input type="reset" value="cancel·la" />
</form>
</body>
</html>

La pàgina de resposta (action-upload.php), aquesta. Comentar aquí com es fa servir l’objecte $_FILES per a obtenir el fitxer pujat,, informació com mida i tipus; i l’us de la funció move_uploaded_file per moure el fitxer del directori temporal al directori de destinació que, en aquest cas, és una carpeta upload dins de la carpeta curl. Cal recordar de donar permís d’escriptura a l’usuari amb que s’executa el php al servidor web sobre el directori de destinació.

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Pàgina de resposta del formulari</title>
</head>
<body>
Valors enviats al formulari<br /><br />
sNom: <?php echo($_POST['sNom']) ?> <br />
sValor: <?php echo($_POST['sValor']) ?> <br />
sCodi: <?php echo($_POST['sCodi']) ?> <br />

<?php if ($_FILES["sUpload"]["error"] > 0) { ?>
S'ha produit un error: <?php echo( $_FILES["sUpload"]["error"]) ?> <br />
<?php } else { ?>
Fitxer d'upload: <?php echo ($_FILES["sUpload"]["name"]) ?><br />
Tipus de fitxer: <?php echo ($_FILES["sUpload"]["type"]) ?><br />
Mida del fitxer: <?php echo (($_FILES["sUpload"]["size"] / 1024)) ?> Kb<br />
<?php move_uploaded_file($_FILES["sUpload"]["tmp_name"], "upload/" . $_FILES["sUpload"]["name"]); ?>
Desat a: <?php echo("upload/" . $_FILES["sUpload"]["name"]) ?>
<?php } ?>
</body>
</html>

L’anterior pàgina de resposta es pot invocar des de línia de comandes amb una instrucció com la següent. La clau és prefixar el fitxer a pujar amb ‘@’

albert@athena:~/Baixades/bin$ curl http://localhost/curl/action-upload.php -FsUpload=@sl4a_r5.apk -FsNom=ALBERT -FsValor=1234546 -FsCodi=id > file.txt 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current 
                                 Dload  Upload   Total   Spent    Left  Speed 
100  858k  100   515  100  857k   9208  14.9M --:--:-- --:--:-- --:--:-- 15.5M

Vet aquí el fitxer descarregat:

albert@athena:~/Baixades/bin$ cat file.txt
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Pàgina de resposta del formulari</title>
</head>
<body>
Valors enviats al formulari<br /><br />
sNom: ALBERT <br />
sValor: 1234546 <br />
sCodi: id <br />

Fitxer d'upload: sl4a_r5.apk<br />
Tipus de fitxer: application/octet-stream<br />
Mida del fitxer: 857.083984375 Kb<br />
Desat a: upload/sl4a_r5.apk</body>
</html>
albert@athena:~/Baixades/bin$

Pujar i obtenir fitxers de servidor FTP

Aprofito que XAMPP m’ofereix un servidor d’FTP local per provar curl amb aquest protocol

hi faig un cop d’ull amb el client d’ftp:

albert@athena:~/Baixades/bin$ ftp localhost 
Connected to localhost. 
220 ProFTPD 1.3.3e Server (ProFTPD) [::ffff:127.0.0.1] 
Name (localhost:albert): albert 
331 Password required for albert 
Password: 
230 User albert logged in 
Remote system type is UNIX. 
Using binary mode to transfer files. 
ftp> ls 
200 PORT command successful 
150 Opening ASCII mode data connection for file list 
drwxr-xr-x   7 albert   albert       4096 Mar  7 22:33 Symfony 
drwxrwxr-x   4 albert   albert       4096 Apr  8 22:32 captcha 
drwxrwxr-x   3 albert   albert       4096 Apr 19 21:14 curl 
-rwxrwxrwx   1 root     root        30894 May 11  2007 favicon.ico 
-rwxrwxrwx   1 root     root          256 Feb  5  2009 index.php 
drwxrwxrwx   2 nobody   root         4096 Jul 15  2009 webalizer 
drwxrwxrwx   7 root     root         4096 Mar  1  2011 xampp 
226 Transfer complete 
ftp> ^C 
ftp> quit 
221 Goodbye.

Amb curl faig un put del fitxer de prova a la carpeta curl/upload. La clau d’aquesta instrucció és la barra del final a ftp://albert:xxxxxx@localhost/curl/upload/ . D’aquesta manera, curl entén que li estem indicant una carpeta de destinació. Sense la barra es creu que és un directori i obtenim un error.

albert@athena:~/Baixades/bin$ curl -TPythonForAndroid_r5.apk ftp://albert:xxxxxx@localhost/curl/upload/ 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current 
                                 Dload  Upload   Total   Spent    Left  Speed 
100  124k    0     0  100  124k      0  1353k --:--:-- --:--:-- --:--:-- 1553k

Una sintaxi alternativa és amb el paràmetre -u, pe a indicar usuari i password
curl -TPythonForAndroid_r5.apk -u albert:xxxxxx ftp://@localhost/curl/upload/

Obtinc el llistat de fitxers pujats (de nou, cal indicar la barra del final)

albert@athena:~/Baixades/bin$ curl -ualbert:xxxxxx ftp://localhost/curl/upload/ 
-rw-r--r--   1 albert   albert     127271 Apr 19 22:01 PythonForAndroid_r5.apk 
-rw-r--r--   1 nobody   nogroup    877654 Apr 19 21:32 sl4a_r5.apk

Per cert, noteu com en l’anterior llistat el fitxer sl4a_r5.apk que ha estat pujat via http, el propietari i el grup són nobody i nogroup, mentre que el que ha pujat per ftp l’usuari i el grup són els utilitzats en l’ftp.

També, puc obtenir un fitxer del servidor. Em descarregaré la font AHGBold.ttf que tinc a la carpeta de securimage.

Primer de tot, examino la carpeta

albert@athena:~/Baixades/bin$ curl -ualbert:xxxxxx ftp://localhost/captcha/securimage/ 
-rw-rw-r--   1 albert   albert     144556 Jan 16 20:16 AHGBold.ttf 
-rw-rw-r--   1 albert   albert       1386 Jan 16 20:16 LICENSE.txt 
-rw-rw-r--   1 albert   albert        398 Jan 16 20:16 README.FONT.txt 
-rw-rw-r--   1 albert   albert       3981 Jan 16 20:16 README.txt 
drwxrwxr-x   2 albert   albert       4096 Jan 16 20:16 audio 
drwxrwxr-x   2 albert   albert       4096 Jan 16 20:16 backgrounds 
-rw-rw-r--   1 albert   albert       1113 Jan 16 20:16 captcha.html 
drwxrwxr-x   2 albert   albert       4096 Jan 16 20:16 database 
-rw-rw-r--   1 albert   albert       8330 Jan 16 20:16 example_form.ajax.php 
-rw-rw-r--   1 albert   albert       7994 Jan 16 20:16 example_form.php 
drwxrwxr-x   2 albert   albert       4096 Jan 16 20:16 images 
-rw-rw-r--   1 albert   albert        491 Apr  8 18:29 prova-form.php~ 
-rw-rw-r--   1 albert   albert      49526 Jan 16 20:18 securimage.php 
-rw-rw-r--   1 albert   albert       1941 Jan 16 20:16 securimage_play.php 
-rw-rw-r--   1 albert   albert       7686 Jan 16 20:16 securimage_play.swf 
-rw-rw-r--   1 albert   albert       3929 Jan 16 20:16 securimage_show.php 
-rw-rw-r--   1 albert   albert       2929 Jan 16 20:16 securimage_show_example.php 
-rw-rw-r--   1 albert   albert       2813 Jan 16 20:16 securimage_show_example2.php 
drwxrwxr-x   2 albert   albert       4096 Jan 16 20:16 words

I ara n’obtinc el fitxer:

albert@athena:~/Baixades/bin$ curl -ualbert:xxxxxx ftp://localhost/captcha/securimage/AHGBold.ttf > AHGBold.ttf 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current 
                                 Dload  Upload   Total   Spent    Left  Speed 
100  141k  100  141k    0     0  1219k      0 --:--:-- --:--:-- --:--:-- 1470k

Notem com l’ha descarregat (Average Dload de 1219k) .

libcurl

Però, el més interessant és que curl es pot enllaçar (libcurl) als nostres programes fets amb C, o Python, o amb algun dels 40 ports a diferents llenguatges que se n’han fet. Fer servir curl per a resoldre les transferències per HTTP, FTP o d’altres protocols no és esnobisme.

Entre la llista de les aplicacions que el fan servir n’hi han de tant populars com OpenOffice.org, Transmission, Xine o GnuPG. En aquest enllàç trobarem una llista d’aplicacions que fan servir Curl.

A la web de Curl podrem trobar exemples d’us de la llibreria.

Exemples amb C
http://curl.haxx.se/libcurl/c/allexamples.zip

Exemples de pycurl (curl amb python) (arxiu .tar)
http://pycurl.cvs.sourceforge.net/viewvc/pycurl/pycurl/examples/?view=tar

Test de Pycurl (arxiu .tar)
http://pycurl.cvs.sourceforge.net/viewvc/pycurl/pycurl/tests/?view=tar

C
Com de fàcil és fer servir curl amb C? La resposta és “molt”. Vet aquí aquest exemple extret de la web de curl. Per a compilar-lo ens caldrà que estigui instal·lat el paquet libcurl4-dev (he instal·lat el libcurl4-openssl-dev. Els protocols segurs poden ser proporcionats per altres llibreries de base, a més d’OpenSSL, com GnuTLS o NSS.

#include 
#include <curl/curl.h>

int main(void)
{
  CURL *curl;
  CURLcode res;

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, 
		     CURLOPT_URL,     
		     "http://www.cs.sunysb.edu/documentation/curl/");

    res = curl_easy_perform(curl);

    /* always cleanup */ 
    curl_easy_cleanup(curl);
  }
  return 0;
}

L’exemple il·lustra com treballar amb libcurl: iniciar la llibreria (curl_easy_init), establir opcions, en aquest cas per a obtenir el contingut de la URL i abocar-lo a la sortida estàndar. Executar l’acció. (curl_easy_setopt estableix les opcions i curl_easy_perform, les executa). Finalment, tancar (curl_easy_cleanup).

Les crides del tipus culr_easy_* permeten accedir a les possibilitats de curl de forma “easy”, fàcil, com el mateix nom indica. Es tracta de la versió síncrona, i ràpida d’usar per a fer transferències. Existeix la versió “multi”, que permet transferències múltiples i asíncrones.

Compilar el programa anterior, executar-lo i examinar-ne el resultat:

albert@athena:~/workspace/wk-c/prova-libcurl$ gcc simple.c -lcurl -o simple-curl
albert@athena:~/workspace/wk-c/prova-libcurl$ simple-curl > pagina.html
albert@athena:~/workspace/wk-c/prova-libcurl$ ls -al
total 64
drwxrwxr-x 2 albert albert 4096 2012-04-22 16:38 .
drwxrwxr-x 12 albert albert 4096 2012-04-22 16:22 ..
-rw-rw-r-- 1 albert albert 38126 2012-04-22 16:38 pagina.html
-rw-rw-r-- 1 albert albert 1353 2012-04-22 16:23 simple.c
-rwxrwxr-x 1 albert albert 8478 2012-04-22 16:38 simple-curl
albert@athena:~/workspace/wk-c/prova-libcurl$ head pagina.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head> <title>cURL - Manual</title>
<link rel="STYLESHEET" type="text/css" href="curl.css">
</head>
<body bgcolor="#ffffff" text="#000000" LINK="#0000ff" VLINK="#808080" ALINK="red">
<table width="100%"><tr>
<td>
<a href="http://curl.haxx.se/"><img border="0" src="ds-curlicon.png" width="99" height="37" alt="cURL"></a>
</td>
albert@athena:~/workspace/wk-c/prova-libcurl$

Python

I amb PyCurl?

L’exemple anterior amb Python, també extret dels exemples:

http://pycurl.cvs.sourceforge.net/viewvc/pycurl/pycurl/examples/basicfirst.py?view=markup

#! /usr/bin/env python
# -*- coding: iso-8859-1 -*-
# vi:ts=4:et
# $Id: basicfirst.py,v 1.5 2005/02/11 11:09:11 mfx Exp $

import sys
import pycurl

class Test:
    def __init__(self):
        self.contents = ''

    def body_callback(self, buf):
        self.contents = self.contents + buf

print >>sys.stderr, 'Testing', pycurl.version

t = Test()
c = pycurl.Curl()
c.setopt(c.URL, 'http://curl.haxx.se/dev/')
c.setopt(c.WRITEFUNCTION, t.body_callback)
c.perform()
c.close()

print t.contents

Copio aquest codi a simple.py, li en dono persmisos d’execució i provo.

albert@athena:~/workspace/wk-python/prova-curl$ simple.py > pagina.html
Testing libcurl/7.21.6 GnuTLS/2.10.5 zlib/1.2.3.4 libidn/1.22 librtmp/2.3
albert@athena:~/workspace/wk-python/prova-curl$ head pagina.html 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD> <TITLE>cURL - Development</TITLE>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<link rel="STYLESHEET" type="text/css" href="/curl.css">
<link rel="shortcut icon" href="http://curl.haxx.se/favicon.ico">
</HEAD>
<BODY bgcolor="#ffffff" text="#000000" LINK="#0000ff" VLINK="#808080" ALINK="red">
<!-- first-line-in-body -->
<table width="100%"><tr valign="top"><td> <a href="http://curl.haxx.se/"><img border="0" src="http://curl.haxx.se/ds-curlicon.png"

En resum, una eina per a transferir informació “cap a” i “des de” servidors http i ftp que es pot encastar als nostres scripts d’administració de sistemes o les aplicacions que desenvolupem.

Com afegir un captcha amb PHP i Securimage

Com fer un captcha amb PHP?

Una de les formes habituals de protegir formularis web de l’acció de robots o programes que fan peticions automàtiques és afegir un captcha.

Els captcha són aquestes paraules generades aleatòriament i que es mostren amb les lletres deformades, ratllades, sobre fons degradats o de trames… de forma que no poden ser reconegudes per programes d’OCR, però sí per operadors humans. Aleshores, per validar el formulari web protegit per un captcha, l’operador humà ha d’encertar la paraula o paraules que “oculta”.

Es tracta d’una prova que permet garantir amb una certesa prou important (si més no, per ara) que qui envia el formulari és una persona i no un robot.

No cal inventar la roda. Per afegir un captcha a les nostres aplicacions web n’hi ha prou amb incorporar alguna de les llibreries que es poden trobar per Internet. Per descomptat, trobarem llibreries de codi obert, i en una varietat de llenguatges.

Amb PHP hem provat aquesta: Securimage. Es pot descarregar de la seva pàgina de download.

A dia d’avui podem descarregar la versió 3. També podem descarregar una pàgina de proves per a determinar si la nostra instal·lació té les versions adequades de PHP i llibreries gràfiques per a suportar-la.

A la web de Securimage (http://www.phpcaptcha.org/) trobarem documentació, FAQ, demos…

A continuació faré un petit exercici per a demostrar com afegir un captcha a una aplicació web.

El plantejament és el següent:

  • Faré un formulari web amb els camps nom, email, i captcha
  • El formulari va a una pàgina de resposta que valida el captcha. Si la validació és correcta, ens donarà un missatge de benvinguda; si la validació no és correcta, ens informarà de captcha erroni.

És dir, dues pàgines php:

  • El formulari web.
  • la pàgina de resposta.

A la QuickStart Guide ens explica com hauran de ser aquestes pàgines.

Estic desenvolupant en un entorn local amb Xampp. He creat una carpeta captcha a l’htdocs. Dins aquesta carpeta he descomprimit la llibreria securimage. Ara tinc, dins de la carpeta captcha, una carpeta securimage amb la llibreria securimage.php i la resta de fitxers auxiliars.

A la carpeta captcha poso la pàgina de formulari. Fixem-nos que és una pàgina php senzilla en la que només hi ha la invocació a la sessió php com a únic codi de servidor. La resta és un formulari web senzill.

El captcha es genera invocant securimage_show.php.al src de l’etiqueta img.

Securimage_show.php amaga una seqüència similar a aquesta:

    require_once 'securimage.php';
    $image = new Securimage();
    $image->show();

El camp d’entrada corresponent al text del captcha és un input type text normal.

En el cas que el text del captcha sigui il·legible, amb el javascript de l’enllaç es torna a invocar securimage_show.php per a generar-ne un de nou. Fixem-nos en l’ús de Math.random() per a evitar problemes de caché..

Vet aquí el codi

<?php session_start(); ?>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Pàgina de prova del formulari</title>
</head>
<body>
<form action="prova-resposta.php" method="post">
Nom: <input type="text" name="sNom" maxlength="20" /><br />
Email: <input type="text" name="sEmail" maxlength="40" /><br />

<!-- el captcha, propiament dit -->
Captcha: <br />
<img id="captcha" src="securimage/securimage_show.php" alt="CAPTCHA Image" /><br />

<!-- el camp d'entrada -->
<input type="text" name="sCaptcha" size="10" maxlength="6" />

<!-- Per si la imatge del captcha no s'entén, es permet la possibilitat de generar-ne un altre-->
<a href="#"
onclick="document.getElementById('captcha').src = 'securimage/securimage_show.php?' + Math.random(); return false">
[ genera un nou captcha ]</a>
<br />
<input type="submit" value="envia"/>
</form>
</body>
</html>

I ara el codi del prova-resposta.php. Aquesta pàgina tindrà com esquelet la següent seqüència de codi:

    require_once 'securimage.php';
    $image = new Securimage();

    if ($image->check($_POST['sCaptcha']) == true) {
      echo "Correcte!";
    } else {
      echo "Codi erroni!";
}

Vet aquí el codi:


<?php session_start(); ?>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Pàgina de resposta del formulari</title>
</head>
<body>
<?php
# carreguem la llibreria
include_once 'securimage/securimage.php';

#instanciem l'objecte de captcha
$securimage = new Securimage();

if ($securimage->check($_POST['sCaptcha']) == true) {
?>
Validació correcte!<br />
paràmetres llegits: <br />
sNom: <?php echo($_POST['sNom']) ?> <br />
sEmail: <?php echo($_POST['sEmail']) ?> <br />
<?php
} else {
?>
Validació incorrecte!<br />
<a href="prova-form.php">Torna a provar</a><br />
<?php
}
?>
</body>
</html>

I un exemple d’execució

i la resposta