Formularios

Esta lección comenta el uso de los formularios HTML para conseguir páginas web PHP interactivas.

Introducción

Los formularios son los elementos de las páginas web que permiten a un usuario introducir información en una página web. Así, los formularios nos permiten crear páginas web PHP interactivas en las que el contenido de la página se adapta a la información proporcionada por el usuario.

En el caso más simple, se suelen distribuir las tareas en dos páginas independientes:

pagina-1.php (formulario) Formulario Nombre: Fulanito Curso: Enviar al pulsar Enviar pasa a la 2ª página action pagina-2.php (resultado) Resultado ¡Hola, Fulanito! Estudia Segundo. Volver al formulario al hacer clic en el enlace vuelve a la 1º página href

El ejemplo siguiente corresponde a la imagen anterior (la página con el formulario se llama form-1-1.php y la página que recibe los datos se llama form-1-2.php):

Enlace a ejemplo

Creación de formularios

Las etiquetas de HTML que permiten la creación de formularios y de los diferentes tipos de controles (cajas de texto, casillas de verificación, botones radio, etc.) se comentan en las lecciones Formularios (1) y Formularios (2) de los apuntes de Páginas web HTML y hojas de estilo CSS.

Este curso de PHP se centra en el tratamiento de los datos proporcionados por el usuario mediante el uso de formularios, no en el diseño de formularios. De hecho, en la mayoría de ejercicios propuestos en estos apuntes, los formularios están incluidos en las plantillas de los ejercicios y el alumno no necesita crearlos, pero se recomienda tener un conocimiento general de las etiquetas y atributos relacionados con formularios.

Recepción de los datos

Cuando un formulario envía los datos a una página PHP, los datos están automáticamente a disposición del programa PHP en una matriz llamada $_REQUEST. Cada dato recibido es un elemento de la matriz $_REQUEST: el índice del elemento es el nombre del control y el valor del elemento es el dato introducido o seleccionado por el usuario en el control.

Nota: Si el atributo name contiene espacios en blanco, puntos o el carácter [ (sin el carácter ]), estos se convierten en guiones bajos en la matriz $_REQUEST.

En el siguiente ejemplo, el programa que recibe los datos del formulario simplemente muestra el contenido de la matriz $_REQUEST utilizando la función print_r() que muestra los índices y valores de la matriz. La página con el formulario se llama form-2-1.php y la página que recibe los datos se llama form-2-2.php

<?php
// form-2-2.php
print "<pre>";
print_r($_REQUEST);
print "</pre>\n";
?>
Enlace a ejemplo

Como se puede comprobar en el ejemplo anterior, el control de caja de texto crea siempre un elemento en la matriz $_REQUEST (aunque la caja de texto se deje vacía), mientras que el botón radio solamente crea un elemento en la matriz $_REQUEST si se elige una de las opciones del botón radio.

En la lección Controles en formularios de estos apuntes se detallan las particularidades de cada tipo de control.


Los valores que se reciben de un formulario son siempre de tipo cadena, aunque sean valores numéricos. Sin embargo, los nombres de los controles que se reciben de un formulario (y que se convierten en índices de la matriz $_REQUEST) pueden ser de tipo entero (si son números enteros) o de tipo cadena (si no son números enteros). Los nombres de los controles pueden tener estructura de matriz, incluyendo corchetes.

<form action="form-6-2.php" method="get">
  <p>Nombre: <input type="text" name="nombre"></p>

  <p>Edad: <input type="number" name="1"></p>

  <p>
    Aficiones:
    <input type="checkbox" name="aficion[1]"> Deporte
    <input type="checkbox" name="aficion[2]"> Lectura
  </p>

  <p><input type="submit" value="Enviar"></p>
</form>
Enlace a ejemplo

Visibilidad de los datos enviados: el atributo method

El atributo method de la etiqueta <form> permite elegir si la información de los controles se incluye en la URL de llamada a la página (method="get") o se incluyen en las cabeceras HTTP (method="post"). Si no se incluye el atributo method, el comportamiento predeterminado es el mismo que con get, es decir, los datos se incluyen en la URL.

La diferencia es que con el valor get se pueden ver en la barra de dirección los nombres de los controles y los valores introducidos por el usuario, mientras que con el valor post no. Los datos recibidos son los mismos y desde el punto de vista de la seguridad ambos métodos son equivalentes (es decir, inseguros si se utiliza http y seguros si se utiliza https).

Normalmente, los formularios disponibles en Internet utilizan el método post, de manera que las URL sean más "limpias" al no contener los datos de los formularios. Pero en estos apuntes, los formularios utilizan el método get, de manera que se puedan simular fácilmente ataques de inyección, como se comenta en el apartado siguiente.


PHP incluye en la matriz $_REQUEST todos los datos que llegan junto con la petición de la página, tanto si están incluidos en la URL como si están incluidos en cabeceras HTTP. PHP también crea otras dos matrices, $_GET y $_POST, que contienen los datos recibidos por uno de los métodos, $_GET los recibidos en la URL (get) y $_POST los recibidos en cabeceras (post).

Ataques de inyección

Es importante ser consciente de que cualquier página PHP puede recibir datos y que se pueden enviar datos a cualquier página PHP. Enviar datos a una página que no espera recibir datos no suele afectar al funcionamiento de la página y por tanto no suele suponer un riesgo de seguridad, pero si hablamos de una página que espera recibir datos de un formulario, entonces estamos ante la posibilidad de que la página sea "atacada" con datos inesperados que sí pueden afectar a su funcionamiento. Este tipo de ataques se denominan en general ataques de inyección y pueden ser de muy diversa naturaleza, según cuál sea el objetivo del ataque.

Por ello, una página que reciba datos de un formulario debe protegerse ante este tipo de ataques. Por ejemplo, debe funcionar correctamente aunque no le lleguen los datos esperados o aunque los datos no tengan el formato esperado.

Para realizar un ataque de inyección, basta con editar la URL y modificar los datos, borrando, modificando o añadiendo nuevos datos, respetando la notación ?clave1=valor1&clave2=valor2 .... Puede abrir el ejemplo siguiente en una nueva pestaña y modificar la URL como se muestra en las capturas siguientes.

Enlace a ejemplo

Si el programa PHP trabaja con $_REQUEST o $_GET, el ataque de inyección se puede realizar manipulando la URL. Si el programa PHP trabaja con $_POST, el ataque de inyección se tendría que realizar con alguna herramienta que generara las cabeceras HTTP.

Recepción segura de los datos

Los programas que recogen datos de formularios necesitan protegerse de los ataques de inyección. En estos apuntes, se recomienda:

Las soluciones de los ejercicios propuestos siguen las recomendaciones de estas lecciones.