PHP-TUT-09 Formularios en PHP (I)

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

A lo largo de los artículos anteriores hemos empezado a vislumbrar una pequeña parte de la flexibilidad que PHP nos ofrece para manejo de datos. Sin embargo, todavía no sabemos cómo proporcionarle a nuestro script los valores con los que debe trabajar. Hasta ahora hemos almacenado esos valores muy pobremente como parte del código. Sin embargo, es lógico que el usuario deba pasarle a un script algunos datos a través de un formulario.

ENVÍO DE DATOS DESDE UN FORMULARIO

Hemos mencionado anteriormente el caso de que alguien pueda querer ver un listado de empresas de un determinado sector en su ciudad. Así pues, el usuario deberá poder decir qué sector es el que le interesa. Esto se puede hacer mediante un formulario que contenga un campo de tipo lista donde se pueda elegir una opción. Esa opción se pasa al script PHP para que, a su vez, la procese como sea necesario (de esto último ya nos ocuparemos en porsteriores artículos). Observa el script elegirSector.htm, que contiene un formulario con una lista de posibles sectores. En realidad he abreviado la lista para que no ocupe mucho, pero para el ejemplo nos sirve perfectamente.

Cuando empleamos un formulario donde el usuario debe escribir algo en campos de texto, o seleccionar opciones de una lista, o marcar casillas de verificación, etc., dicho formulario tiene, como atributo action, el nombre del script que recopilará los datos del usuario y los procesará en el servidor (incluyendo la ruta, si fuera diferente de la actual, lo que no es el caso, en este ejemplo).

Para cargar esta página en el navegador usa la notación que ya conoces: teclea, en la barra de direcciones, http://localhost/fourmularios/elegirSector.htm (suponiendo que hayas alojado el script en un directorio llamado formularios en tu localhost) y pulsa Intro. El aspecto de la página es similar al que se ve a continuacion:

El formulario con un desplegable para elegir sector.

El formulario con un desplegable para elegir sector.

Ves que tiene una lista desplegable en la que puedes elegir una opción. Fíjate en el listado. La lista se llama sector. Tiene cuatro opciones cuyos valores van de cero a cuatro. Elige una opción y pulse el botón ENVIAR. En este momento, el formulario llama al script cuyo nombre tiene en el atributo action, y le pasa una variable con el nombre del campo select y el valor de la opción seleccionada. Si el formulario tuviera más campos, pasaría una variable por cada campo. El script está en elegirSector.php, que aparece a continuación:

En la primera línea defino una matriz que contiene las profesiones. Fíjate en que están dispuestas de tal modo que cada una tiene un índice que coincide con el atributo value de las option de la página anterior.

En la segunda línea recuperamos la variable enviada desde el formulario, tal cómo se detalla en la zona sombreada a continuación.

EL ENVÍO

Cuando unamos un formulario éste tiene un atributo llamado method, en el que se especifica el método de envío al script receptor de los datos (el que figura en el atributo action).

Los métodos de envío pueden ser get o post. Cuando enviamos un formulario por get, los pares nombre valor viajan hasta el destino en la URL. Se añaden automáticamente a la URL en el momento del envío, de modo que aparecen en la barra de direcciones del navegador, aunque no los hayamos escrito específicamente. Por ejemplo, en el caso anterior, si hubiéramos usado get, al pulsar el botón ENVIAR la URL que veríamos en el navegador sería la siguiente:

http://localhost/formularios/elegirSector.php?sector=1

Cuando enviamos el formulario por post, los datos del mismo viajan “ocultos” (no aparecen en la URL). Esto da cómo resultado dos cosas: en primer lugar, la URL en el navegador aparece “limpia”. A la vista del usuario es más agradable. En segundo lugar, no proporcionamos información a un posible atacante sobre la naturaleza de los datos enviados. Esto no es ninguna tontería. Los datos de un formulario se pueden ocultar en el HTML si hacemos que se generen dinámicamente en tiempo de ejecución, pero si luego aparecen en la URL, estamos ofreciendo información que podría revelar alguna vulnerabilidad.

Además de lo anterior, el envío de datos por get tiene ciertas limitaciones. La primera es la longitud de la query string que se genera cómo URL. Esta tiene un máximo, que viene determinado por el navegador y el servidor. Apache, por ejemplo, soporta un máximo de 4000 caracteres por defecto, aunque esto es configurable (si tienes acceso a la configuración del servidor, desde luego). Algunos navegadores antiguos (y todavía quedan funcionando más de los que nos gustaría) no reconocen nada por encima de 256 caracteres.

También hay datos que, por su propia naturaleza, sólo se pueden enviar por post, cómo son los campos de fichero. Cuando tenemos el típico campo que nos permite enviar una imagen, un pdf, o cualquier otro archivo, sólo puede enviarse por post. Aprenderemos a enviar archivos más adelante.

LA RECEPCIÓN

Cuando el script PHP recibe los datos de un formulario enviado, estos quedan almacenados en memoria en una matriz especial, propia del lenguaje. Esta matriz es $_POST, cuando el formulario se ha enviado con el método post o $_GET, cuando se ha enviado por el método get. Cada par nombre valor genera un elemento en la matriz correspondiente. La clave del elemento es el nombre del campo (el atributo name en el formulario) y su valor es el que haya tecleado el usuario. A partir de ahí, podemos usar este elemento directamente en nuestro código, o pasar su contenido a una variable de memoria, así (por ejemplo):

$nombre = $_POST["campo_de_nombre"];

En versiones antiguas de PHP (las anteriores a la 5), la variable de memoria se creaba automáticamente a partir del dato enviado por el formulario. Esto se debía a una variable de configuración de PHP llamada Register Globals que, por defecto, estaba activada. Los creadores de PHP se dieron cuenta de que esto suponía un importante agujero de seguridad y, desde la versión 5 venía desactivada. Además, en la versión 5.4 se eliminó definitivamente, con lo que, actualmente, no hay posibilidad de activarla.

Existe una matriz propia de PHP llamada $_REQUEST, que contiene los pares nombre valor de la misma forma, con la salvedad de que están ahí, tanto si han sido enviados por post cómo por get. De hecho, la matriz $_REQUEST también almacena datos de otros orígenes, pero de eso hablaremos en otros artículos.

La experiencia de los años me ha enseñado que, siempre que sea posible, enviaremos por post los datos, y los recuperaremos desde $_POST. Cuando no haya más remedio (en algunos casos no podemos hacerlo de otro modo), enviaremos por get, y recuperaremos por $_GET o por $_REQUEST, pero son opciones que, a priori, debemos descartar.

En la tercera línea muestro el valor de la variable $sector.

Por último, en la cuarta línea muestro el elemento de la matriz que corresponde a la opción elegida. Prueba esto varias veces, seleccionando distintas opciones, para ver que funciona correctamente.

Vamos a ver otro ejemplo, para afianzar mejor la comprensión del funcionamiento de este mecanismo. Observa el código formularioSimple.htm:

El formulario generado con formularioSimple.htm

El formulario generado con formularioSimple.htm

Ejecuta la página. Verás que es un formulario que pide una serie de datos. El aspecto es similar al que se ve en la figura reproducida a la izquierda:

 

Quizás el aspecto no es muy elaborado. Podríamos haber usado una tabla, o capas, para colocar cada cosa en su sitio, CSS para darle estilos al texto y los campos, etc. Da igual. Lo que nos interesa ahora es ver cómo funciona todo esto. Teclea tu nombre donde se te pide, marca la casilla de “soltero” (no importa ahora si lo eres o no) y selecciona el botón de radio correspondiente a tu edad. A continuación pulsa en ENVIAR y mira lo que ocurre cuando se llama a formularioSimple.php, cuyo código es el siguiente:

En la pantalla de tu navegador verás los datos enviados por el formulario.

Quiero que observes que he puesto, en el código, unas comillas simples acotando cada dato, y así aparecen en el resultado. He hecho esto por una razón: vuelve a ejecutar formularioSimple.htm y, en esta ocasión, NO marques la casilla de verificación que corresponde a soltero ni ninguno de los botones de edad. Pulsa en ENVIAR  y verás el resultado con las variables vacías, y unos avisos de error, así.

Datos vacíos generan avisos de error.

Datos vacíos generan avisos de error.

Cuando se envían campos de un formulario a un script PHP hay que tener en cuenta este tipo de cosas. Un campo de casilla de verificación o de botones de radio que no ha sido seleccionado no le llega al script receptor. Si el campo ha sido seleccionado, envía como valor aquél que tenga en el atributo value. Por esta razón, cuando haya la posibilidad de que un campo no esté cumplimentado por el usuario, deberemos preveerlo. A continuación aparece una versión modificada de formularioSimple.php, en la que hemos usado la función isset() y el operador ternario que ya conocemos, para que, si no existe el campo en la matriz $_POST (que es dónde debemos de buscarlo), nos asigne un valor por defecto (por ejemplo, una cadena nula, o lo que decidamos).

Una alternativa es asegurarnos de que todos los campos tengan un valor, antes del envío del formulario mediante el uso de JavaScript, cómo vemos en establecerOculto.htm:

El funcionamiento del javascript que hemos puesto es muy simple y, además, queda fuera del objetivo de este artículo, por lo que no vamos a detenernos en él. no obstante, voy a aprovechar para hacer una puntualización que sí considero relevante. Muchas personas confunden, al principio, el uso de los atributos id y name de los campos de formularios. Son parecidos y aquí vamos a aclarar la diferencia:

El atributo id se emplea para reconocer un elemento en la propia página, y gestionarlo desde JavaScript en el lado del cliente. Este atributo no sobrevive cuando se envia el formulario y no le llega al script receptor. NUNCA (y repito: NUNCA) pongas dos elementos (sean campos de formulario, capas, tablas, párrafos, o cualesquiera otros) en la misma página con el mismo valor de id. Cada elemento de la página debe tener un id diferente.

El atributo name es el nombre con el que el campo pasa al script receptor. Cada campo debe tener un valor de name diferente, excepto los botones de radio de un mismo grupo, ya que cumple dos objetivos. Por una parte, le dice al navegador qué botones pertenecen a cada grupo, de modo que sean excluyentes (al seleccionar uno, se deselecciona cualquier otro que hubiera seleccionado previamente). Además, al script receptor le llega un par nombre-valor con el name de los botones del grupo y el valor (value) del que esté seleccionado.

PÁGINAS AUTO PROCESADAS

Cuando se trata de enviar un formulario a un script del servidor, puede ocurrir que queramos tener el código del script en el mismo listado que el formulario. Es lo que se conoce con el nombre de páginas auto procesadas. La principal característica de este tipo de páginas, desde el punto de vista de la programación, es que el atributo action del formulario que contienen no recibe ningún valor, de modo que cuando se pulsa el botón destinado a enviar el formulario, este se carga contra la propia página. Esto implica varias cosas. Para empezar, la página tiene que “comprobar” si acaba de ser llamada por el navegador cliente o si ha sido llamada por el envío de su propio formulario, ya que, en el primer caso tiene que mostrarle al usuario la parte HTML (el  mencionado formulario y los posibles contenidos visuales) y en el segundo caso tiene que procesar los datos y mostrar los resultados. Veamos un ejemplo de esto en autoprocesada.php.

Al cargar la página en el navegador sólo verá un campo de texto, con la etiqueta Nombre: para que el usuario introduzca el nombre. Al pulsar el botón ENVIAR se carga la misma página (observa el atributo action del formulario) y muestra el valor de la variable.

Yo no soy especialmente partidario del uso de esta técnica, salvo en casos muy específicos. Cuando manejes formularios complejos, que cargan contra scripts complejos, verás que usar páginas auto procesadas es, por decir lo mínimo, una de las mejores formas de meterse en problemas. De todos modos, con el tiempo y la experiencia, tu instinto y tu conocimiento te dirán cuándo puede ser interesante considerar esta técnica.

En el próximo artículo aprenderemos a enviar ficheros a través de un formulario, recibirlos en el servidor, y almacenarlos o hacer con ellos lo que proceda.

     

2 comentarios:

  1. Pingback: PHP-TUT-10 Formularios en PHP (y II) » eldesvandejose.com

  2. Pingback: PHP-TUT-11 Manejo de datos (I) » eldesvandejose.com

Deja un comentario

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