La p√°gina de DriverOp

Recuperar datos de un formulario.


Aquí desarrollaré un método para recuperar datos de un formulario que el usuario ya ha enviado al servidor y este lo rechaza.

Introducción.

El problema es simple y bastante com√ļn. El usuario llena un formulario. Introduce datos err√≥neos, faltantes o inconsistentes y el servidor los rechaza devolvi√©ndolo al formulario de ingreso, pero el usuario ahora tiene que comenzar todo de nuevo. Esto puede ser frustrante para el usuario si se trata de un formulario con datos delicados o con muchos campos para rellenar.

Entonces es mejor que el servidor le ayude recuperando los datos que el usuario ya ha enviado poniéndoselos en su lugar para que el usuario solo tenga que modificar y/o completar lo que está mal o faltante.

La soluci√≥n que implementar√© aqu√≠ utiliza HTML y PHP √ļnicamente concentr√°ndome solo en el problema planteado dejando para el lector la tarea de determinar cu√°ndo y por qu√© un dato es err√≥neo. Aunque es verdad que los datos de un formulario hoy en d√≠a se pueden verificar usando algo de JavaScript, no todo tipo de dato puede ser validado usando JS, por ejemplo, saber si un n√ļmero de cliente existe en la base de datos remota exige que el cliente haga una petici√≥n al servidor, algo que JavaScript por s√≠ mismo no podr√≠a hacer (incluso con AJAX!).

Mi solución divide el problema en dos partes. La primera parte es la recogida de datos, esto se traduce en un formulario HTML (tag form). La segunda parte es la validación de datos luego de que el usuario ha enviado esos datos al servidor para ser validados. Esto se traduce en dos archivos diferentes. Al primero lo llamaré formulario.php y al segundo validador.php.

Provisiones del sistema.

Ambos componentes del sistema, formulario y validador, trabajan en conjunto. Mientras que el primero espera que el segundo se encargue de la validación, el segundo espera que el primero recoja los datos. El problema aparece porque el modelo HTTP es unidireccional. Esto quiere decir que el servidor no hace nada a menos que el cliente se lo pida, mientras que en un sistema de validación de datos exigie que el servidor le ordene al cliente que corrija los datos cuando encuentra que estos son, de alguna manera, erróneos.

Para subsanar esto recurriré a algunos mecanismos previstos por el protocolo HTTP, como ser la redirección automática, y del lenguaje PHP, que tiene la capacidad para administrar sesiones en el sevidor.

Esto de las sesiones implementadas por PHP es una gran ventaja que nos ayudar√° a resolver el problema en cuesti√≥n. Es importante que el lector entienda el concepto detr√°s de las sesiones en PHP. B√°sicamente una sesi√≥n es un espacio de almacenamiento de informaci√≥n en forma de variables que son persistentes al cambio entre la ejecuci√≥n de un script y otro; y a su vez, permiten que cada espacio de almacenamiento sea √ļnico para cada visitante del sitio web, de forma tal que dos usuarios distintos accediendo a las mismas p√°ginas no se interfieran entre s√≠. En otras palabras, a cada usuario le corresponde una sesi√≥n y el estado de una, no afecta el estado de la otra.

Esto quiere decir que los datos persisten para un usuario durante toda su estadía en el sitio permitiéndole al servidor trasladar datos de una ejecución a otra para ese usuario.

Este mecanismo es sencillo de manejar en PHP y bastante transparente en cuanto a su implementaci√≥n para nosotros los programadores. Solo hay que tener una precauci√≥n importante: Si durante la ejecuci√≥n de un script PHP se necesita acceder a una variable de sesi√≥n, la sesi√≥n debe ser iniciada o reiniciada antes de enviar ning√ļn dato al cliente. No puede ejecutarse un "echo" o un fragmento de c√≥digo HTML o tan siquiera un espacio vac√≠o o retorno de carro hacia el navegador. Esto se debe a que las sesiones hacen uso de cookies que se almacenan en el cliente y el protocolo HTTP dispone que las cookies se envian como cabeceras (headers) de una p√°gina. Y las cabeceras siempre se envian ANTES que cualquier otra cosa cuando un navegador intenta cargar una p√°gina web.

PHP tiene una función estandar para indicar que se usará una sesión, la cual es session_start(). Esta función es la que envia las cabeceras requeridas al cliente y por tanto es la que primero debe ejecutarse antes de enviar cualquier otra cosa al navegador. Una vez que se ha ejecutado esa función ya podemos acceder a cualquier variable de sesión.

Las variables de sesión en PHP están contenidas en un array superglobal cuyo identificador es $_SESSION[]. Esta variable es un array asociativo donde cada posición de ese array puede contener cualquier dato, incluso otros arrays.

En orden a implementar una solución para el problema planteado haré uso de sesiones en PHP. Con lo explicado hasta aquí es fácil darse cuenta que este mecanismo es bastante obvio como solución.

El formulario.

Pasemos entonces a implementar el formulario con su script PHP asociado. He aquí el código fuente del archivo que llamaré "formulario.php".

session_start(); 
$nombre = "";
$apellido = "";
if (isset($_SESSION["datos"])) {
$nombre = $_SESSION["datos"]["nombre"];
$apellido = $_SESSION["datos"]["apellido"];
}
?>







En primer lugar y antes que nada se abre una sesión. Luego se inicializan un par de variables que se corresponden con los datos que se piden en el formulario. A continuación se pregunta si existe el array $_SESSION["datos"], si es así, entonces se procede a extraer los datos del array. La parte de PHP explicada aquí la explicaré más profundamente más adelante.

Finalmente, ya en el código HTML se muestran los valores de ese par de variables donde va el parámetro "value" de los inputs los cuales son cajas de textos.

Aquí el mecanismo descanza sobre la asunción de que si existe el array $_SESSION["datos"] implica que el usuario ya pasó por este formulario y ese array debería contener los datos ingresados por el usuario la vez anterior. Sin embargo el amable lector se estará preguntando dónde se han asignado esos valores para el array $_SESSION["datos"]. Esa tarea es del siguiente script, el que recibe los datos que el usuario ha ingresado.

El validador.

En el código anterior vemos que el parámetro "action" del "form" apunta al script validar.php, este script es el encargado de hacer algo con los datos que el usuario ha escrito. He aquí el código fuente del script.

session_start();
 
$_SESSION["datos"] = Array();
$nombre = @$_POST["nombre"]; $_SESSION["datos"]["nombre"] = $nombre;
$apellido = @$_POST["apellido"];
$_SESSION["datos"]["apellido"] = $apellido;
$err = false;
if (validar_nombre($nombre) == false) { $err = true; }
if (validar_apellido($apellido) == false) { $err = true; }
if ($err == true) { header("Location: formulario.php"); exit; }
// resto del código aquí...
unset($_SESSION["datos"]);
?>

Se comienza (re)iniciando la sesi√≥n. Luego se inicializa el array $_SESSION["datos"]. Esto se hace porque se asume que si ese array ya exist√≠a debido a un rechazo anterior de los datos, esos datos ya no son v√°lidos, los que contar√≠an como nuevos son los datos que ahora mismo el usuario ha ingresado. Pero si es la primera vez que el usuario ha enviado los datos desde el formulario, entonces se crea ese array como tal, como un array. A continuaci√≥n se extraen los datos que el usuario envi√≥ desde el array superglobal $_POST puesto que ese es el tipo de petici√≥n especificado en el "method" del "form". El "@" delante de $_POST hace que si esa posici√≥n en el array no existe, la variable que est√° a la izquierda del signo igual quede definida pero vac√≠a, es una peque√Īa medida de seguridad.

Al mismo tiempo se pasa el valor extra√≠do as√≠ hacia el array de sesi√≥n, este paso es muy importante y es el n√ļcleo de la soluci√≥n implementada.

Luego se establece una variable tipo bandera que indicará al final del proceso de validación, si hubo un error en los datos o no. Por omisión se asume que no habrá errores.

Las funciones "validar_nombre" y "validar_apellido" implementarán los códigos necesarios para determinar si las variables $nombre y $apellido contienen valores válidos, se espera en este ejemplo que esas funciones devuelvan un valor booleano. Las implementaciones de estas dos funciones serán a gusto del lector, aquí solo se mencionan a modo de ejemplo. En caso de que alguna variable resulte tener un dato inválido, la variable de bandera $err tomará valor "verdadero".

Lo que resta por hacer es determinar el valor de esa variable bandera. En caso de haber error, se redirecciona al cliente a que vuelva a cargar la página "formulario.php" mediante el uso de la función estandar de PHP header() y se fuerza a que termine el script ahí mismo. Caso contrario se puede proceder a poner el resto del código que el lector crea conveniente (por ejemplo aquí se puede hacer una inserción o modificación de una base de datos).

Finalmente se destruye el array $_SESSION["datos"]. Esto se hace porque si éste script llegó al final, significa que los datos que aportó el cliente fueron usandos adecuadamente y ya no es necesario volver a mostrárselos al usuario en caso de que visite de nuevo el formulario.

¬ŅPor qu√© funciona?.

La primera vez que el usuario visita "formulario.php" el if que determina si $_SESSION["datos"] existe resultará falso. Por lo tanto los dos inputs tipo texto se mostrarán vacíos, listos para que el usuario los rellene.

Pero si ese if resulta verdadero implica que el usuario fue forzado a recargar el formulario debido a la ejecución de la función header() que está en validar.php y por lo tanto $_SESSION["datos"] contiene los mismos datos que ya había ingresado. Y así los inputs mostrarán los datos que el usuario ingresó la vez anterior.

Consideraciones finales.

Lo explicado hasta aquí y el ejemplo implementado es nada más que para mostrar la funcionalidad básica de la solución propuesta. Hay muchos detalles en el camino que habría que controlar pero que escapan al propósito de este artículo. Un ejemplo de ello es que debido a la forma en que PHP y el servidor web trata ciertos caracteres en el array $_POST, el usuario podría no tener exactamente la misma cadena de texto que él ingresó. Esto es cierto en el caso de las comillas simples o dobles.

Una forma de controlar esto sería así:

if (get_magic_quotes_gpc()) {
$nombre = stripslashes($nombre); }

Este código iría en el script validar.php.

En el ejemplo se asume que los datos que se le piden al usuario son nuevos datos y no modificación de datos que ya están contenidos en otra parte. Por ejemplo si el formulario sirve para modificar datos que están en una base de datos. En ese caso este ejemplo ya no funciona sin una extensa revisión de la lógica del mismo.

Otro detalle que no está en el ejemplo es que si bien funciona como solución, el usuario no es informado de ninguna manera de por qué sus datos fueron rechazados. El lector tendrá también la tarea de modificar adecuadamente el código presentado aquí para suplir esta falencia.

Si tienes preguntas o comentarios sírvete usar mi formulario de contacto.

Diego Romero - .