Validar datos recibidos de un formulario

Doble validación

En los capítulos anteriores se observó la necesidad de filtrar los datos recibidos para eliminar caracteres no deseados. Luego vimos que debemos identificar los campos y formularios esperados. Si todo esto se cumple sólo nos resta comprobar que los datos recibidos se ajustan a los requeridos. ¿Y porqué hay que hacerlo?. Para nuestro objetivo definimos un campo de un formulario como una pareja compuesta por un nombre de campo y un valor. Aunque a veces usemos el término datos de un formulario, realmente nos estamos refiriendo a esos campos de un formulario. Los datos recibidos de un formulario siempre tienen algún destino. Por ejemplo:

  • Dar de alta un nombre de usuario y contraseña en un registro de usuarios, una base de datos por ejemplo, para permitir que se autentique posteriormente leyendo y comprobando los datos con los registrados.
  • Recoger los datos de una compra: referencia artículo y número de unidades a comprar.
  • Recibir una dirección de email y un mensaje para luego enviarlo como email a otra dirección propiedad del administrador del sitio (el típico formulario de contacto con reenvío al correo del administrador).
  • Recoger mensajes para un foro.
  • Etc.

En definitiva, con los datos hacemos algo. Supongamos que alguién se da de alta en nuestro sistema de autenticación con un nombre de usuario excesivamente largo con objeto de ralentizar hasta llegar a bloquear el sistema. O que nos envían un número negativo de unidades de artículos de compra, lo que podría significar una devolución en lugar de una compra. O que alguién nos envía una dirección de email incorrecta o con cabeceras inadecuadas, de tal forma que luego nos perjudicará de alguna forma cuando nosotros, como administradores del sitio, recibamos ese correo. Y aunque el riesgo no produzca daños ¿qué necesidad tenemos de recibir datos que no hemos solicitado?.

En mi glosario XHTML+CSS hice dos ejemplos básicos relacionados con el recibido de datos en el servidor:

En el primero de los ejemplos anteriores se realizaba una validación de los datos antes de que éstos se enviaran al servidor. La validación consistía en código JavaScript que validaba los tipos de datos en el navegador del usuario. Pero esto requiere que el navegador tenga activado JavaScript, por lo que debería también requerirse una segunda validación en el servidor por si el primer control no se llevara a cabo por alguna razón. El segundo ejemplo de los anteriores haría este cometido, aunque de forma muy básica. Ambos ejemplos ahora deberían mejorarse e integrarse en lo que podemos denominar una doble validación, tanto en el cliente como en el servidor, aplicando además lo visto sobre la seguridad con formularios en PHP.

Podría pensarse que pasar ambos controles sería una carga excesiva, pero también es razonable exponer que si un usuario envía datos sin validar y esta tarea la hacemos en el servidor, supone una carga para las comunicaciones tener que volver a responderle al usuario que un tipo de datos no es el esperado. Parece mejor y más rápido comprobar en el navegador que lo que el usuario ha introducido en cada campo es lo esperado. Así cuando ya remita el formulario, éste vendrá validado desde origen. Por supuesto, luego pasamos en el servidor una segunda validación por si algo pudiera haberse modificado por el camino de forma malintencionada por un tercero.

Validación de formularios

Desarrollamos un primer ejemplo form1.php con pocos campos para entender el funcionamiento de la validación. Para nuestro propósito podemos precisar que validar un formulario supone llevar a cabo las siguientes acciones, entendiendo que un formulario se compone de campos que se identifican con un nombre y que cada campo porta un valor:

  1. Identificar el formulario: Usando lo visto en un tema anterior sobre la forma en que podemos corroborar que el formulario recibido se corresponde con uno que envíamos previamente.
  2. Identificar los nombres de los campos: Sólo podemos recibir campos con nombres esperados, pues en otro caso debemos descartar todos los valores recibidos.
  3. Verificar la longitud de cada valor: Los valores enviados siempre se reciben como texto. Por lo tanto debemos especificar una longitud máxima y mínima para cada campo y no recibir valores que no estén en ese rango.
  4. Verificar los tipos de campos: Los tipos de campos se verifican con expresiones regulares, por lo que si por ejemplo esperamos un número entero, sólo recibiremos un número entero, devolviendo el formulario al usuario hasta que arregle ese campo.
Hemos dicho que cada campo porta un único valor, pues también podría ser posible los campos multivalorados. Por ejemplo, el campo de tipo <select> permite seleccionar más de un valor con el atributo multiple (verlo en mi glosario XHTML+CSS). Sin embargo la posibilidad de campos multivalorados no la he contemplado en estos procesos de validación que se verán a continuación.

Para entender globalmente el proceso de validación podemos observar este diagrama de flujo. Las flechas verdes representan salidas afirmativas de las bifurcaciones mientras que las marrones son negativas. Las flechas azules representan entradas y salidas a la página.

diagrama del proceso para definir, construir y validar un formulario

Este diagrama refleja la ejecución del citado ejemplo form1.php, presentando un simple formulario para un hipotético registro, con un campo para el nombre de usuario y otro para la contraseña. Desglosamos el proceso en tres scripts (puede consultar todos los códigos):

Noviembre 2013

El ejemplo de este tema form1.php y el del tema siguiente form2.php usaban originalmente los scripts valida-form.php y /res/inc/valida-form.js. Esos originales se usaban también en este sitio para las páginas de contacto.php y el buscador.php, pero han sido objeto de varias modificaciones. He preferido seguir manteniendo las primeras versiones para estos ejemplos pero las he renombrado como valida-form-obs.php y /res/inc/obs/valida-form.js. El PHP original se sigue llamando valida-form.php mientras que el JS original luego se renombró como validador-form.js.

  1. El script form1.php contiene el proceso de flujo general del diagrama anterior. Para una mayor seguridad usaremos sesiones con objeto de identificar al usuario (navegador) y al formulario, tal como expusimos en el ejemplo identificando el formulario con una sesión del tema sobre CSRF. En este script también definimos los campos que se usarán.
  2. El script valida-form.php que se encarga de las siguientes tareas:
    • Array $patrones_tipos: Se declaran los patrones de las expresiones regulares que nos permitirán validar los tipos de los campos. Hay una función construir_array_patrones() cuya finalidad explicaremos más abajo.
    • function construir_array_js(): Construir una cadena HTML con un literal de un elemento <script> que contendrá copia del array anterior para usar con JavaScript. Este array tendrá exactamente los mismos patrones para enviar al navegador del usuario y que éste se encarge de la validación con JavaScript. Se incluye en la tarea del rectángulo azul del diagrama de flujo, donde se construye y ofrece el formulario.
    • function recibir_campos(): Recibir los campos desde el array $_POST, identificar el formulario y filtrar con htmlspecialchars(). Si se identifica el formulario se guardan los campos en un nuevo array listos para la posterior validación. Se trata de la tarea "RECIBIR CAMPOS" expuesta en el diagrama de flujo.
    • function validar_form(): Utilizando el array de patrones, procedemos a validar los campos filtrados con la función anterior. Es la tarea "VALIDAR FORMULARIO" del diagrama de flujo.
    • function construir_form(): Adicionalmente podemos construir dinámicamente el formulario con PHP, aunque también podría hacerse manualmente. Es parte de la tarea del recuadro azul del diagrama de flujo.
    • Hay dos funciones accesorias que nos permitiran listar y extraer los campos ya validados (function extraer_valores() y function listar_campos()).
  3. Por último el script valida-form.js realizará la validación en el navegador del usuario.

La idea de separar las funciones genéricas en el módulo valida-form.php tiene como finalidad reutilizar este código para todos los formularios del sitio. Así podríamos tener todos los patrones en este módulo y actualizarlos o mejorarlos en un único lugar. Luego ampliaremos esto con más detalle. El script form1.php es básicamente el mismo que usamos en el ejemplo citado de CSRF, exponiendo a continuación una parte del mismo para explicar algunos detalles:

... Declaraciones de sesión y otras variables generales
//Esta constante da el nombre al campo identificador de formulario.
define("IDENTIFICAFORM", "identifica-form1");
... Declaraciones de sesión y otras variables generales
//Incluimos aquí el script que valida el formulario
include "valida-form.php";
//Array con la definición y valores de campos
$array_campos = array(
    IDENTIFICAFORM => array(
        "valor" => "",
        "titulo" => IDENTIFICAFORM,
        "tipo" => IDENTIFICAFORM, 
        "longitud-min" => 32,
        "longitud-max" => 32,
        "requerido" => true,
        "tag" => "input",
        "atributos" => array(
            "type" => "hidden",
            "class" => PREFIJOVAL
            )
        ),
    ...
    "user" => array(
        "valor" => "",
        "titulo" => "Usuario",
        "tipo" => "usuario", 
        "longitud-min" => 4,
        "longitud-max" => 10,
        "requerido" => true,
        "tag" => "input",
        "atributos" => array(
            "type" => "text",
            "class" => PREFIJOVAL
            )
        ),
    ...
);    
//Construimos el array de patrones para esta definición
contruir_array_patrones($array_campos);

En el inicio se ubican la declaración de sesión y de otras variables generales del módulo. A continuación incorporamos un include para incluir el script valida-form.php. Luego declaramos un array con la variable $array_campos que contiene la definición de campos exclusiva para el formulario que vamos a presentar. Por eso esta definición tiene que ir en la misma página php que genera el formulario, mientras que el script valida-form.php será genérica para todos los formularios.

El array de definición de campos se indexa por nombres de campos. Es decir, la clave del array será luego el nombre del campo que irá en el formulario. Por ejemplo, en el formulario tendremos un campo <input name="user" ... para poner el nombre de usuario. Cada entrada del array es a su vez otro array para albergar el valor, el título o etiqueta que acompañará al campo, el tipo de patrón para la validación, la longitud mínima y máxima en caracteres, si es requerido o se permite que venga vacío, el tag o elemento HTML y los atributos de ese elemento.

En lo anterior vemos dos definiciones de campos como ejemplo introductorio, pues en el siguiente capítulo trataremos más a fondo este aspecto. Vemos que la primera entrada del array es para el campo oculto (tipo "hidden") donde llevamos el identificador del formulario. El segundo es un campo de texto, donde acompañamos el atributo type = "text" para crear el elemento <input type="text" name="user" .... También tenemos class = PREFIJOVAL, donde la constante se declara en el script valida-form.php con valor "val-". Los campos que tengan una clase que empiece por "val-" serán validados y el resto se aceptarán sin validar. En ese caso debemos poner class = "noval-" o cualquier otra cadena de al menos 4 caracteres pero que no empiece por ese prefijo.

Después de declarar el array de definiciones ejecutamos la función construir_array_patrones(). En valida-form.php tenemos el array $array_patrones_base que contiene todos los patrones genéricos, pero es posible que muchos de ellos no se vayan a utilizar en el formulario actual. Hacemos un trasvase al $array_patrones de sólo los patrones que usemos con esta definición. Así ahorramos manejar un array excesivo. Además como el array de patrones se envía en en array Javascript al navegador del usuario, evitamos no llevar sino lo justo para validar en el navegador.

Siguiendo con este script form1.php, a continuación del array que define los campos pasamos a iniciar el proceso de control de sesión de forma parecida al ejemplo señalado de CSRF. Si no hay sesión o el usuario la ha finalizado, regeneramos el identificador y declaramos las dos variables de sesión que identifican el usuario ("ident1") y el formulario ("ident2). En este caso guardamos este último valor en el campo que ya hemos visto definido antes.

...
//Iniciamos el proceso de control de sesión
if (!$hay_sesion || ($hay_sesion && !$hay_post) || $finaliza_sesion) {
    //Con sesiones no iniciadas, iniciadas sin post o finalizadas
    $hay_regeneracion = true;
    session_regenerate_id(true);
    $_SESSION["ident1"] = md5($_SERVER["HTTP_USER_AGENT"]);
    $_SESSION["ident2"] = md5(uniqid(rand(), true));
    //Guardamos el valor del identificador de formulario en el array
    $array_campos[IDENTIFICAFORM]["valor"] = $_SESSION["ident2"];
} else {//Con sesiones iniciadas y con POST
    //¿es el mismo usuario?
    if (isset($_SERVER["HTTP_USER_AGENT"])) $usuario_identificado = 
                ($_SESSION["ident1"] == md5($_SERVER["HTTP_USER_AGENT"]));
    //Si se identificó el navegador, vemos si hay POST recibido
    if (($usuario_identificado) && (isset($_POST[IDENTIFICAFORM]))){
        //Recibimos los campos y nos devuelve si se identificó el formulario
        $form_identificado = recibir_campos($_POST, $array_campos, $_SESSION["ident2"]);
        if ($form_identificado){
            //Validamos los campos del formulario
            $mensaje_validar = validar_form($array_campos);
            if ($mensaje_validar == "") {
                //Si no hay mensajes es que el formulario es válido
                $form_validado = true;
                //En ese caso destruimos la sesión actual y la cookie del navegador
                //pues los datos validados serán enviados a otro proceso (aunque
                //en este ejemplo se limita a presentarlos otra vez
                $_SESSION = array();
                if (ini_get("session.use_cookies")) {
                    $params = session_get_cookie_params();
                    setcookie(SESION, '', time() - 42000,
                        $params["path"], $params["domain"],
                        $params["secure"], $params["httponly"]
                    );
                }
                session_destroy(); 
                //Aquí iría el proceso de destinar los datos validados en $array_campos
                //a algún sitio (archivo, base de datos, etc) y luego redirigiría a
                //algúna otra página para seguir algún otro proceso. En este ejemplo
                //volvemos a presentar esta página presentando los datos en pantalla. 
            }
        }
    }
}
?>
...

Como vemos, si en cambio la sesión ya fue iniciada, verificamos si el usuario es el mismo que el que inición la sesión. En ese caso procedemos a identificar el formulario. Para ello usamos la función recibir_campos() del otro script valida-form.php, el cual nos devolverá true o false si se identifica el formulario o no. También actualiza el array de campos donde se almacenan los valores recibidos por el POST. Si se identificó el formulario pasamos a validarlo, usando para ello la función validar_form() también ubicada en ese otro script valida-form.php. Si el mensaje recibido es vacío, supone que los datos han sido validados y podemos ejecutar algún proceso que maneje esos datos, por ejemplo contrastarlos con los almacenados en una base de datos para en su caso permitir el acceso del usuario a otros recursos. En este ejemplo nos limitaremos a devolverlos usando la misma página. A continuación vemos el HTML que hemos puesto en ese mismo script form1.php :

    ...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    ...
    <script type="text/javascript" src="valida-form.js" charset="UTF-8"></script>
    <?php if (!$form_validado) echo construir_array_js(); ?>        
</head>
<body>
    ... 
    <?php 
    if ((!$form_identificado)||($form_identificado && !$form_validado)) {
        ?>
        <p>Se necesitan cookies para recibir este formulario.</p>
        <noscript>
            <p class="verde">Se recomienda activar Javascript para facilitar el 
            uso de este formulario.</p>
        </noscript>   
        <?php
        if (!$form_identificado && !$hay_regeneracion){
            echo "<p style='color: red'>El formulario no se pudo identificar. Por ".
            "favor, reinicie el formulario.</p>";
        } else {
            echo construir_form($array_campos, $mensaje_validar);
        }?>
        <form  action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post">
            <input type="submit" name="fin-sesion" value="reiniciar formulario" />
        </form>            
    <?php        
    } else {
        ...
        ...presentamos los datos recibidos
        ...
    }
    ...
</html>

Vemos que vinculamos el script valida-form.js de JavaScript para que el navegador realice el validado en el lado del cliente. Además pasamos el array de patrones con la función construir_array_js() que está ubicada en valida-form.php. En un siguiente apartado explicaremos con más detalle este array de patrones de expresiones regulares. Por último se construye el formulario, donde la parte de campos se rellena dinámicamente con la función construir_form() que está en valida-form.php. Si los datos no son válidos se presentan los mensajes de error, por eso pasamos como argumentos el $array_campos y los mensajes de error en $mensaje_validar. La función construye completamente el formulario, incluyendo botones de envío y borrado y también la lista de mensajes de error. Existe otro formulario con sólo el botón de envío "fin-sesion". Se trata del formulario que permitirá al usuario finalizar la sesión, aunque se presenta como una opción para reiniciar el formulario. Su finalidad se explicó en el ejemplo de CSRF señalado.

Si ejecuta el ejemplo podrá ver al pie un recuadro con texto en gris que sirve para exponer las variables de sesión y otros detalles (tal como vimos en otros capítulos anteriores). También hay una casilla de verificación que permitirá saltarse la validación en el navegador y enviar los datos para pasar la segunda validación en el servidor. Otro botón rellenará con valores de ejemplos los campos.

Principios de validación

Antes de exponer como se lleva a cabo el proceso de validación, conviene fijar unos principios de validación en los que nos apoyaremos para llevarla a cabo. Alguno de ellos ya los hemos mencionado antes:

  1. Doble validación: El proceso de validación debe ser el mismo y realizarse en el navegador antes de remitir el formulario y luego en el servidor. En un apartado anterior ya razonamos sobre esta necesidad. Una forma de hacer equivalente la verificación de tipos es mediante expresiones regulares, pues se trata de una técnica bastante estándarizada y que puede funcionar tanto en el servidor con PHP como en el navegador con JavaScript con el mismo resultado. Por supuesto, siempre y cuando tengamos en cuenta de usar sólo aquellos aspectos comunes a ambos lenguajes.
  2. Manejar como texto: Todos los valores se reciben como texto, pues así son remitidos con el protocolo HTTP. Y como texto deben guardarse y manejarse.
  3. Controlar longitudes mímina y máxima: Como todos los campos vienen como texto, hemos de verificar la longitud máxima y mínima que debe tener el campo. Si no se exige una longitud mínima, es decir, si el campo no es requerido, ponemos un cero en la longitud mínima.
  4. Campos requeridos: Se debe informar al usuario de los campos que son requeridos.
  5. Valores iniciales: Los campos con listas, como los <input type="radio"> y <select>, deben tener una opción por defecto que se corresponde con la inicialmente enviada al usuario y que supone un valor sin especificar por el usuario. Además los campos númericos deben ser inicializados con un número, usualmente un cero. Así el usuario recibe un valor de inicio orientativo y al mismo tiempo se remitirá este valor si el usuario no lo modifica. Los campos de texto se pueden inicializar con una cadena vacía "".
  6. Informar de todos los errores: Deben validarse todos los datos (nombres de campos y valores) con la finalidad de entregar un informe de todos los errores al usuario. Así éste podrá arreglarlos todos de una vez y enviar de nuevo el formulario. Puede ser frustrante para el usuario las típicas "idas" y "venidas" de formulario que informan inmediatamente tras descubrir el primer error.
  7. No arreglar los errores: Si hay un error en un dato, debe ser el usuario y no el algoritmo quién repare ese error. Se pueden hacer validaciones basadas en funciones del lenguaje, como por ejemplo solicitar un número entero y pasarle el método de JavaScript parseInt para convertirlo obligatoriamente en un entero. Pero creo que no es un enfoque adecuado validar en base a suposiciones sino entregar un informe de errores y que sea el usuario quién los arregle.

Realizar validaciones usando funciones de JavaScript que evalúan un campo y en algún caso incluso lo "arregla" puede ser atractivo para el programador. De hecho ya expuse en otra parte de este sitio un script en Javascript llamado javascript-general-codigo.html. Se trata de un recurso que agrupa todas aquellas funciones de uso genérico para todo el sitio web. Se incluyen también las funciones que unifican distintos comportamientos de los navegadores. De hecho es un archivo que está en permanente evolución, a veces añadiendo nuevas funciones y otras veces modificándolas o eliminándolas porqué ya no son necesarias. Incluye algunas validaciones individuales y arreglos como por ejemplo:

  • controlaTextarea()
  • evaluaNumero()
  • evaluaNumeroEntero()
  • arreglaNumero()
  • arreglaNumeroEntero()
  • limitaValor()

Evidentemente podrían usarse en el navegador para controlar campos numéricos, pero si sólo lo basamos en esto perdemos el enfoque del principio de la doble validación y el de no arreglar errores. Además realizar validaciones de esta forma para todos los tipos de campos posibles puede resultar en un conjunto muy grande de funciones JavaScript de díficil manejo. Más adelante veremos que es más cómodo agregar un nuevo patrón de expresión regular que construir una nueva función expresamente para validar un nuevo tipo de campo.

Aunque en algún caso podríamos aprovecharnos de algunas facilidades. Por ejemplo, sabemos que en el navegador del usuario no podemos controlar que el texto que va introduciendo un usuario en un elemento <textarea> supere un cierto límite de caracteres. Con un <input type="text"> si lo podemos hacer con el atributo maxlength, pero no hay algo similar para el <textarea>. Así usamos la función controlaTextarea() pero esto no debe impedir que también se valide ese campo con el mismo proceso que el resto.

Otro posible ejemplo sería limitar un valor númerico para un campo en un rango. Si tenemos un <input type="text"> donde el usuario tendría que introducir un número natural entre 10 y 20, por ejemplo, podemos realizar un "arreglo" con Javascript si el valor se sale de este rango.

Estas utilidades Javascript pueden facilitar al usuario la introducción de los datos. Pues si no se controlan en el navegador en el momento en que el usuario introduce el valor, resultará que se le irán acumulando errores y cuando envie el formulario tendrá una larga lista de errores que arreglar. Pero en nuestro proceso podemos incluir estas funciones Javascript dentro de la entrada "atributos" de la definición del array, como un evento. Por ejemplo:

  • Para controlar un número máximo de caracteres en un <textarea> definimos en su entrada
    "atributos" => array(...
        "onkeypress" => "javascript: controlaTextarea(this, event, 150);"
        ... 
  • Para controlar un valor númerico en un rango de un <input type="text">
    "atributos" => array(...
        "onblur" => "javascript: limitaValor(this, 'entero', 10, 20);"
        ... 

De todas formas considero que no se debería abusar de esta forma de proceder. Piense que el ejemplo que limita el campo con valores en el rango 10-20 se ejecuta en el navegador, por lo que se rompe el principio de la doble validación. En el servidor no tendremos nada previsto para controlarlo (a no ser que hagamos una expresión regular para ello), por lo que siempre que sea posible es preferible apoyar la validación con expresiones regulares.

El proceso de validación

El proceso de validación se produce en los scripts valida-form.php y valida-form.js para PHP y JavaScript respectivamente. El algoritmo de validación es equivalente en ambos sitios, es decir, se trata en definitiva del mismo algoritmo aunque adaptado a cada lenguaje y situación. Recordemos que la validación se hacía en dos fases:

  1. Llamando a la función recibir_campos() de valida-form.php procedemos a recoger los campos que llegaron vía POST. Un campo debe ser el identificador de formulario. Si se recibe y contiene el mismo valor que el almacenado en la variable de sesión entonces damos por bueno el resto de campos recibidos. Si se recibe un campo no esperado descartamos todos los datos. Todo los valores son filtrados con htmlspecialchars() según se extraen del array $_POST y se almacenan en la variable de definición de campos array_campos, en su entrada "valor".
  2. Una vez identificado el formulario pasamos a validar los datos usando la función validar_form() también del script valida-form.php.

En este apartado no se expone el código de estos scripts, pero puede consultarlos en los enlaces anteriores. Creo que es mejor usar diagramas de flujo y ver los detalles en el código, donde se incluyen comentarios descriptivos. Por un lado el recibido de campos con la función recibir_campos() tiene el siguiente diagrama de flujo:

diagrama del proceso para identificar y recibir campos de un formulario

Las flechas en azul representan las entradas y salidas del algoritmo. Las verdes son salidas afirmativas de las bifurcaciones y las marrones son las negativas. También realizamos un proceso para controlar los valores de elementos verificación, es decir, de elementos como <input type="checkbox">, aunque hemos obviado esta parte en el diagrama para que resulte más claro. Esa parte simplemente se dedica a controlar todos los checkbox, pues el navegador no enviará aquellas verificaciones que no hayan sido activadas por el usuario. Lo que hacemos es ir contando las recibidas y al finalizar el bucle, antes de salir del script, procedemos a desactivar los valores en el array de definiciones $array_campos de las que no fueron recibidas. Esto lo puede observar en el código.

Se observa que hacemos un proceso de recortado de las cadenas de texto recibidas. En principio la validación de la longitud se realiza en la siguiente función validar_form(), pues aquí sólo estamos filtrando los valores del array $_POST y pasándolos a otro array $array_campos. Pero no podemos permitir que venga un valor con un texto excesivamente largo, por lo que procedemos a realizar un recortado provisional al doble de la longitud requerida. No recortamos a la longitud exacta porque si hay un error devolveremos los datos al usuario para que compruebe que es lo hay que arreglar. En el caso de exceso de longitud es preferible que sea el usuario el que corte, partiendo del principio que expusimos más arriba: si hay un error en los datos, debe ser el usuario y no el algoritmo quién repare ese error.

Un vez recibidos los campos usamos la función validar_form() que tiene el siguiente diagrama de flujo:

diagrama del proceso para validar un formulario

Se revisan los campos uno a uno, concatenando mensajes de error de cada campo. Al final si no hay errores tendremos un mensaje vacío que se devolverá y que indicará que no se produjeron errores. En otro caso lo que tenemos es una lista de errores.


En el capítulo siguiente detallaremos como llevar a cabo la definición de campos. También veremos los patrones a usar en las expresiones regulares que verifican los tipos de campos.