Imagen de validación de formularios con PHP

Con este tutorial vamos a ver otra forma de validación de formularios con PHP mediante la generación de una imagen aleatoria, que NO guardaremos en disco.

Imagen de validación de formularios con PHP

Introducción

Actualmente, cuando una web desea obtener datos de un usuario le
proporciona un formulario que debe rellenar con la información
que se desea recoger y que serán guardados (normalmente) en
una base de datos.

Esto se hace para evitar evitar que programas automatizados
rellenen las bases de datos que recogen esta información de basura.

Para este gran problema, actualmente se opta por enviar una
imagen aleatoria (que contiene un texto
alfanumérico) junto con el formulario. De manera que cuando
el
usuario desee enviar los datos, deba indicar que texto es el que se
muestra en la imágen.

(Estos programas automatizados, normalmente no son capaces de detectar
que texto se muestra en la imagen, por lo que nuestra web
estará
libre de su ataque malicioso).

El motivo de este tutorial es
intentar utilizar otra técnica

que la que se ven en otros tutoriales que hay en el Web. Desde mi punto
de vista la técnica que se muestra en estos tutoriales es
mejorable, pues lo que hacen es generar una imagen aleatoria y
guardarla en el disco duro del servidor y permanece hay mientras el
usuario no envie el texto de validación correcto… Esto
hace
que el servidor se llene de miles de imágenes y sea
costosisimo
luego de eliminar a mano. (Por supuesto siempre se puede hacer un
script que las borre automáticamente utilizando
algún
criterio. Por ejemplo, que borre aquellas imágenes que
lleven
más de una hora en el disco duro.

Nosotros lo vamos hacer igual, pero sin guardar ninguna imagen en el disco duro del servidor.. más que nada por que
creo que no hace falta hacerlo para llegar al fin deseado.

Vamos a ver un Ejemplo

Este es el Script al que accede el usuario y que envia el
formulario
que tiene que rellenar el usuario. El script es autocomentado (Todo el
código fuente debería serlo) .

  <?php
  /*
  	@author. Carlos García Pérez. Autentia Real Business Solutions
  	Este Script inicia la sesión si no estaba iniciada ya y envia el formulario a rellenar al usuario
  */ 
  
  // Iniciamos la sesión
  session_start();
  if (! isset($_SESSION["imageText"])){
   // No estaba creada la sesión, la creamos.
   // Generamos una cadena aleatoria que será la se envie como imagen al usuario. 
   $_SESSION["imageText"] = generateRandString(4);
   
   session_write_close();
  }
  
  /**
   * Genera una cadena aleatoria de 'numChars' caracteres. 
   */ 
  function generateRandString($numChars){
   // Quitamos los caracteres {0, 1, i, l, o) pues confunden 
   // mucho a los usuarios ya que por ejemplo un cero y una o se ven más o menos
   // igual.
   
  	$chars = "AaBbCcDdEeFfGgHhJjKkMmNnPpQqRrSsTtUuVvWwXxYyZx23456789";
  	$charsCount = strlen($chars) - 1;
  	$randString = "";
  	
  	for ($i=0; $i < $numChars; $i++){
        $num = rand(0, $charsCount);
        $randString .= $chars[$num];
  	}
  	
  	return $randString;
  }
  ?>
  
  
    Autentia Real Business Solutions
    
    
  
  
    

Comentarios:

Este es el Script

Text
getImage.php

genera la imagen asociada a la variable almacenada en sesión.

<?php
/*
	@author. Carlos García Pérez.
	@company. Autentia Real Business Solutions
	Este script genera la imagen de validación del formulario
*/ 

session_start(); 

$imageText = $_SESSION["imageText"];

// Verificamos que el usuario inicio sesión
if (! isset($imageText)){
  // El usuario no inicio sessión header("HTTP/1.0 405"); 
  // Recurso no permitido
  return;
}

// Constantes que nos harán el código más legible
define("HEIGHT", 30);
define("SPC", 20);
define("WIDTH", (SPC * strlen($imageText)));
define("FONTNAME", "ARIAL.TTF");
define("FONTSIZE", 18);

/* { Generamos la imagen. }
* Nota:
* Esta parte podría ser cambiada para generar una imagen más compleja de
* averiguar por programas de detección de imágenes.
*/
$img = @imagecreate(WIDTH, HEIGHT);
@imagecolorallocate($img, 200, 200, 200);
$black = @imagecolorallocate($img, 0, 0, 0);
@imagerectangle($img, 0, 0, WIDTH - 1, HEIGHT - 1, $black);
for ($i=0, $l = strlen($imageText); $i < $l; $i++){
  @imagettftext($img, FONTSIZE, 10, $i*SPC + 2, 26, $black, FONTNAME, $imageText[$i]);
}
// Fin { Generamos la imagen }
// Enviamos la imagen al cliente (Navegador, PDA, Móvil, etc). 
// Como veis no se guarda nada en el disco duro pues le enviamos la imagen directamente al cliente. 
@imagepng($img);

// Liberamos recursos
@imagedestroy($img);
?>

El siguiente script

Text
processCommentForm.php

es el que recibe los datos que se envian desde el formulario.

  <?php
/*
	@author. Carlos García Pérez.
	@company. Autentia Real Business Solutions
	Este script valida que el texto introducido por el usuario y si es igual al 
	que estaba guardado en sesión almacenamos los datos en nuestra BD.
*/ 

session_start();

$imageText = $_SESSION["imageText"];

// Verificamos que el usuario inicio sesión
if (! isset($imageText)){
  // El usuario no inicio sesión
  header("HTTP/1.0 405"); // Recurso no permitido
  return;
}

$resultText = "";

// Comprobamos (case-sensitive) que el texto que introdujo el usuario 
// es igual al que estaba guardado en sesión. 

if ($imageText == $_POST["txtRandImage"]){
  // El usuario introdujo correctamente el valor de la imágen 
  // Destruimos todas las variables de la sesión y la sesión en si misma.
  session_unset();
  session_destroy();

  // Aquí procesariamos y guardariamos los datos del formulario (vienen en $_POST) en nuestras BD o ficheros. (En este ejemplo no lo hacemos). 
  $resultText = "Validación correcta. Sus comentarios fueron guardados";
} else {
  $resultText = "Validación incorrecta. Inténtelo de nuevo";
}
// En este ejemplo simplemente se envia un mensaje al usuario.
echo $resultText;
?>

Bueno, espero que os haya sido de utilidad este tutorial.

En Autentia,
empresa en la cual trabajo, nos gusta compartir el conocimiento. Aquí teneis un
poquito más de nuestra aportación. Si
algún día necesitais un poco de ayuda con vuestros proyectos o
necesitais de formación ya sabéis donde
encontrarnos.

Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

He leído y acepto la política de privacidad

Información básica acerca de la protección de datos

  • Responsable: IZERTIS S.A.
  • Finalidad: Envío información de carácter administrativa, técnica, organizativa y/o comercial sobre los productos y servicios sobre los que se nos consulta.
  • Legitimación: Consentimiento del interesado
  • Destinatarios: Otras empresas del Grupo IZERTIS. Encargados del tratamiento.
  • Derechos: Acceso, rectificación, supresión, cancelación, limitación y portabilidad de los datos.
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad

Técnico especialista en informática de empresa (CEU). Ingeniero Técnico en Informática de Sistemas (UPM) Creador de MobileTest, Haaala!, Girillo, toi18n. Charla sobre desarrollo de aplicaciones en Android. @cgpcosmad

¿Quieres publicar en Adictos al trabajo?

Te puede interesar

22/06/2026

Juan Antonio Jiménez Torres

Vamos a instrumentalizar un SDD para un microservicio bancario. En este artículo sobre SDD - Spec Driven Development, instrumentalizado sobre OpenSpec vamos a construir una PoC de algo más serio que una tabla periódica. Un microservicio bancario muy simplificado que gestione cuentas y permita hacer transferencias

16/06/2026

Juan Antonio Jiménez Torres

Este es el segundo artículo sobre SDD, Spec Driven Development, instrumentalizado sobre OpenSpec. Pero esta vez nos acercaremos usando softwere gratuito. Por un lado OpenCode en lugar de ClaudeCode y usando el modelo gratuito Gemma4 de Google en lugar de otros de pago.

08/06/2026

Juan Antonio Jiménez Torres

Aprenderemos sobre SDD – Spec Driven Development instrumentalizado sobre OpenSpec. Haremos un primer acercamiento usando ClaudeCode con Sonnet, para luego, en un artículo posterior pasarnos a la versión gratuita de OpenCode con Gemma4