Gestionar los formularios y los vínculos con PHP
Visión de conjunto
1. Introducción
En los sitios web dinámicos e interactivos, a menudo es necesario interactuar con el usuario.
En HTML, existen dos métodos principales para interactuar con un usuario:
-
los vínculos (etiqueta <a>);
-
los formularios (etiqueta <form>).
Pueden utilizarse scripts PHP para procesar el clic del usuario en un vínculo o la entrada de datos del usuario en un formulario.
2. Los vínculos
El vínculo es la técnica básica que permite navegar a un usuario entre las diferentes páginas de un sitio web. Un vínculo HTML se crea con las etiquetas <a> y </a>.
Sintaxis simplificada
<a
[ action="url" ]
[ id="identificador_vínculo" ]
[ target="meta" ]
>
...
</a>
Los atributos de la etiqueta <a> son los siguientes:
href |
URL (Uniform Resource Locator) relativa o absoluta a la que hace referencia el vínculo; en nuestro caso, un script PHP. Este atributo es obligatorio para adecuarse a la recomendación XHTML estricta. |
id |
Identificador del vínculo. Si la página HTML contiene varios vínculos, el identificador permite diferenciarlos. No obstante, este identificador no tiene mayor interés para nosotros, puesto que no se procesa en el script ligado al vínculo. Por el contrario, puede ser utilizado del lado cliente, en JavaScript, por ejemplo. |
target |
Destino (por ejemplo, otra ventana) en la que abrir la dirección meta. De manera predeterminada, la dirección meta se muestra en la misma ventana. |
La dirección puede contener parámetros que permiten pasar información de una página a otra.
Sintaxis
url_clásica?nombre=valor[&...]
El signo de interrogación (?) introduce la lista de los parámetros de la dirección separados por el carácter et (&); cada parámetro está constituido por una pareja nombre/valor con la forma nombre=valor:
www.misitio.com/info/index.php?nombre=Olivier
buscar.php?nombre=Olivier&apellido=HEURTEL
Ejemplo
-
Script pagina1.php
<?php // Inicialización de una variable. $nombre='Olivier'; ?> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="es"> <head><meta charset="utf-8"...
Recuperar los datos pasados por la dirección
1. Consideraciones
a. ¿Qué pasa si dos parámetros tienen el mismo nombre?
Simplemente será el último parámetro encontrado en la dirección el que establece el valor.
Ejemplo
<a href="pagina2.php?nombre=Olivier&nombre=Xavier">Pagina 2</a>
Esta dirección da una sola variable nombre igual a Xavier en la tabla $_GET.
b. Utilizar una tabla para pasar datos en la dirección URL
Es posible utilizar una notación de tipo tabla en el nombre del parámetro pasado en la dirección URL.
Ejemplo
<a href="pagina2.php?data[]=HEURTEL&data[]=Olivier">Pagina 2</a>
Esta dirección facilita una variable data, de tipo tabla, que contiene las siguientes líneas:
Clave |
Valor |
0 |
HEURTEL |
1 |
Olivier |
PHP rellena la tabla añadiendo una línea para cada parámetro, con un índice entero consecutivo que comienza en 0 (como para la notación [] estudiada en el capítulo Introducción a PHP - Las bases del lenguaje PHP).
Esta técnica es interesante, pero, en el código, hay que saber que el índice 0 corresponde al apellido y el índice 1 al nombre. Por otro lado, puede haber un problema si el orden de los parámetros cambia.
Para mejorar esta técnica, es posible establecer uno mismo la clave, bien con un número, bien con una cadena de caracteres.
Ejemplo
<a href="pagina2.php?data[apellido]=HEURTEL&data[nombre]=Olivier">
Pagina 2</a>
Esta dirección da el siguiente resultado en la tabla data:
Clave |
Valor |
apellido |
HEURTEL |
nombre |
Olivier |
2. Transmitir caracteres especiales
Si el valor que debe transmitirse no contiene caracteres especiales (espacio, signo y (&), signo de interrogación (?), etc.), puede colocarse directamente en la dirección como indicábamos anteriormente. En caso contrario, es necesario codificarlo para asegurarse de que esos caracteres particulares se interpretan correctamente.
Por ejemplo, si los datos pasados en la dirección contienen «Olivier & Xavier», sólo Olivier se recuperará al final, ya que & se interpreta como el separador de parámetros....
Recuperar los datos introducidos en el formulario
1. Consideraciones
a. ¿Qué pasa si dos zonas tienen el mismo nombre?
Simplemente será la última zona en el formulario la que establezca el valor.
Ejemplo
<form action="formulario.php" method="POST"><div>
Apellido: <input type="text" name="apellido"><br />
Nombre: <input type="text" name="apellido"><br />
<input type="submit" name="aceptar" value="Aceptar">
</div></form>
Introducir HEURTEL en la primera zona y Olivier en la segunda zona da una única variable igual a Olivier en la tabla $_POST.
b. ¿Qué pasa si hay dos formularios en la página HTML?
Solo se crearán variables y se asignarán valores para el formulario que haya sido validado.
Ejemplo
<form action="formulario.php" method="POST"><div>
Apellido 1: <input type="text" name="apellido1"><br />
<input type="submit" name="aceptar1" value="Aceptar1">
</div></form>
<form action="formulario.php" method="POST"><div>
Apellido 2: <input type="text" name="apellido2"><br />
<input type="submit" name="aceptar2" value="Aceptar2">
</div></form>
Si el usuario valida el primer formulario, la variable apellido1 estará disponible. Si el usuario valida el segundo formulario, la variable apellido2 estará disponible.
c. Utilizar una tabla para recuperar los datos introducidos
Es posible utilizar una notación de tipo tabla en el atributo name de las etiquetas <input>, <select> y <textarea>.
Ejemplo
<form action="formulario.php" method="POST"><div>
Apellido: <input type="text" name="entrada[]"><br />
Nombre: <input type="text" name="entrada[]"><br />
<input type="submit" name="aceptar" value="Aceptar">
</div></form>
La entrada de HEURTEL en la primera zona y de Olivier en la segunda da una única variable entrada de tipo tabla que contiene las siguientes líneas:...
Controlar los datos recuperados
1. Visión de conjunto
En la primera parte de este capítulo, hemos visto cómo recuperar los datos pasados en una dirección URL o introducidos en un formulario.
Después, hay que comprobar que los datos recuperados son correctos, es decir, que respetan las reglas de gestión definidas para la aplicación.
Para la seguridad del sitio web, conviene siempre sospechar de los datos que vienen del exterior (formulario, dirección URL y también, lo veremos más adelante, cookies, etc.). Estos datos deben controlarse y filtrarse para evitar los ataques potenciales de un usuario malintencionado.
El objetivo de esta parte es dar algunas pistas sobre las técnicas utilizadas habitualmente en PHP para esta comprobación. En el caso de un formulario, otro enfoque posible consiste en realizar un control en JavaScript en el explorador, cuyo interés reside en evitar un envío al servidor.
Los diferentes ejemplos presentados en esta parte utilizan formularios. Deben efectuarse las mismas comprobaciones respecto a los datos pasados en la dirección.
2. Comprobaciones clásicas
a. Limpieza de los espacios innecesarios
La función trim (véase el capítulo Utilizar las funciones PHP - Manipular las cadenas de caracteres) puede utilizarse para eliminar los «vacíos» innecesarios al principio o al final de la cadena. En el caso de un formulario, este proceso se aplica sobre todo a las zonas de entrada de texto libre (<input> de tipo text o password, <textarea>).
Ejemplo
// Recuperar el valor introducido en la zona "nombre" y limpiar
// los espacios innecesarios (al principio y al final).
$nombre = trim($_POST['nombre']);
b. Dato obligatorio
Comprobar si un dato obligatorio está presente es muy sencillo: solo hay que comprobar si la variable asociada contiene un valor.
Ejemplo
$nombre = trim($_POST['nombre']);
if ($nombre == '') {
// $nombre vacío = zona "nombre" no introducida => hacer algo
}
c. Longitud máxima de una cadena
La longitud de los datos recuperados puede controlarse con la función strlen (véase el capítulo Utilizar las funciones PHP - Manipular las cadenas de caracteres). En el caso de un formulario, este proceso se aplica sobre todo a las zonas...
Problemas con los datos recuperados
Un problema de visualización en una zona de formulario puede producirse si el dato mostrado contiene unas comillas (").
Ejemplo
Código fuente de la página en el explorador (fragmento)
<form action="formulario.php" method="post">
<div>
Nombre: <input type="text" name="nombre"
value="dice: "¡Hola!"" />
<input type="submit" name="aceptar" value="Aceptar" />
<br />dice: "¡Hola!" </div>
</form>
En HTML, en los atributos (value, name…) de las etiquetas, el delimitador de cadena son las comillas. En el atributo value, la secuencia «dice: » es considerada como el valor del atributo y el resto de la cadena es ignorado. El problema se produce incluso con el carácter \, ya que este último no es un carácter de escape en HTML.
Otro problema de visualización puede producirse si el dato mostrado contiene etiquetas HTML.
Ejemplo
La entrada Olivier <b>Heurtel da la palabra Heurtel en negrita en la visualización en la página HTML. La etiqueta <b> introducida por el usuario se encuentra tal cual en el código fuente de la página y, por lo tanto, es interpretada por el explorador como la marca de negrita.
Por último, podemos encontrar un tercer problema en la entrada de datos en un área de texto.
Ejemplo
Una entrada de datos en varias líneas en un <textarea> se muestra correctamente en la zona de texto, pero sin los saltos de línea en la página HTML. El texto está presente con saltos de línea en el código fuente de la página, pero el salto de línea, fuera de un <textarea>, es ignorado por el explorador: hay que poner una etiqueta <br />.
Vemos, por lo tanto, tres problemas relacionados con la presentación en pantalla de datos procedentes de una fuente externa (formulario, dirección URL, etc.):
-
presencia de las comillas que puede plantear un problema en la utilización del dato en un formulario (atributo value);
-
presencia de etiquetas HTML válidas que son interpretadas como tales por el explorador;
-
saltos de línea ignorados presentes...
Utilización de los filtros
1. Principios
Esta extensión permite filtrar y validar datos, sobre todo los que proceden de la entrada de los usuarios o de una URL.
Cada filtro es definido por un número (identificador), un nombre y, si es necesario, opciones e indicadores que detallan el comportamiento del filtro. Cada opción se establece mediante un nombre utilizado como clave en una tabla asociativa. Cada indicador viene dado por una constante; para especificar varios indicadores, solo hay que añadir las constantes correspondientes.
Algunos ejemplos de filtros (véase la documentación para la descripción de todos los filtros):
Identificador (constante predefinida) |
Descripción |
FILTER_VALIDATE_INT |
Valida un valor como entero. Las opciones min_range y max_range permiten definir un intervalo de validez. |
FILTER_VALIDATE_FLOAT |
Valida un valor como número de coma flotante. Una opción decimal permite especificar el carácter utilizado como separador decimal y una opción thousand el carácter utilizado como separador de millares. Las opciones min_range y max_range permiten definir un intervalo de validez. Para autorizarla presencia de los separadores de millares, hay que utilizar además el indicador FILTER_FLAG_ALLOW_THOUSAND. |
FILTER_VALIDATE_REGEXP |
Valida un valor mediante una expresión regular compatible con PERL. La expresión regular que debe utilizarse se especifica gracias a la opción regexp. |
FILTER_VALIDATE_EMAIL |
Valida un valor como dirección electrónica. |
FILTER_SANITIZE_STRING |
Elimina las etiquetas contenidas en una cadena y codifica los caracteres ’ y ". Varios indicadores están disponibles para eliminar o codificar caracteres suplementarios (véase a continuación). Obsoleto a partir de la versión 8.1 (en su lugar, utilizar la función htmlspecialchars que se ha presentado anteriormente). |
FILTER_SANITIZE_ SPECIAL_CHARS |
Codifica en HTML los caracteres ’, ", <, > y &, así como todos los caracteres de código ASCII inferior a 32. Varios indicadores están disponibles para eliminar o codificar caracteres suplementarios (véase a continuación). |
FILTER_SANITIZE_ ADD_SLASHES |
Añade un carácter contrabarra (\) delante de los caracteres apóstrofo (’), comilla ("), contrabarra... |
Ir a otra página
En el proceso efectuado por un script PHP, puede ser necesario mostrar otra página.
El caso puede darse, por ejemplo, al final del proceso del formulario, y la situación puede variar en función de si el formulario es procesado por el script que lo muestra o por un script independiente.
Posibles variantes:
Formulario procesado por: |
||
Resultado del procesamiento |
El script de visualización |
Otro script |
OK |
|
|
Problema |
|
|
Es posible redirigir al usuario hacia otra página durante la ejecución del script utilizando la función header, que permite enviar encabezados HTTP con la página HTML (véase el capítulo Utilizar las funciones PHP - Manipular los encabezados HTTP).
Vamos a utilizar el encabezado location que redirige la consulta hacia otra dirección.
Sintaxis de la directiva location
location: URL absoluta o relativa
Sintaxis con la función header
header('location: URLabsoluta o relativa')
Ejemplos
// Redirección hacia un script PHP situado en el mismo nivel.
header('location: error.php');
// Redirección hacia una página HTML situada en un subnivel.
header('location: ./error/mensaje.htm');
// Redirección hacia otro sitio web.
header('location: http://www.olivier-heurtel.fr');
El protocolo HTTP 1.1 requiere una dirección absoluta en la directiva location. Para ello, puede utilizar las variables globales $_SERVER[’HTTP_HOST’] y $_SERVER [’PHP_SELF’] (véase el capítulo Anexos - Variables PHP predefinidas).
Ejemplo
<?php
$url_relativa = 'error.php';
echo '$url_relativa = ',$url_relativa,'<br />';
echo '$_SERVER[\'HTTP_HOST\'] = ',
$_SERVER['HTTP_HOST'],'<br />';
echo '$_SERVER[\'PHP_SELF\'] = ',
$_SERVER['PHP_SELF'],'<br />';
echo 'dirname($_SERVER[\'PHP_SELF\']) = ',
dirname($_SERVER['PHP_SELF']),'<br...
Enviar un archivo desde el cliente y el servidor
1. Visión de conjunto
Algunos sitios web pueden ofrecer a los usuarios transferir documentos desde su equipo al servidor web: mandar un CV (sitio web de búsqueda de empleo), adjuntar documentos a un mensaje (sitio web de correo electrónico) o simplemente almacenar el documento en el servidor (sitio web de almacenamiento).
En la terminología anglosajona, este característica se denomina «file upload».
Inversamente, muchos sitios web permiten a los usuarios descargar («download») documentos desde el servidor web a su equipo.
Estas dos características son aplicaciones particulares de las técnicas presentadas en este capítulo.
2. Cargar un archivo a partir del cliente: «file upload»
Esta funcionalidad, muy sencilla de poner en práctica en PHP, requiere dos operaciones:
-
en un formulario, mostrar una zona que permita al usuario especificar la ubicación del archivo en su equipo;
-
en el script de procesamiento del formulario, recuperar el archivo enviado por el usuario y hacer algo con él.
En la primera parte de este capítulo, hemos visto la posibilidad de poner en un formulario una zona para especificar la ubicación de un archivo en un equipo (type="file").
Poner una zona de este tipo no es suficiente. Para que se realice la transferencia del archivo, hay que añadir el atributo enctype="multipart/form-data" en la etiqueta <form>:
<form action="formulario.php" method="post"
enctype="multipart/form-data">
Esta técnica solo funciona con los formularios que utilizan el método POST.
Además, es posible añadir una zona oculta en el formulario para limitar el tamaño de los archivos que pueden enviarse hacia el servidor. Esta zona oculta, obligatoriamente situada antes de la zona de tipo file, debe llamarse MAX_FILE_SIZE (atributo name) y especificar el tamaño máximo en octetos en el atributo value:
Ejemplo de zona oculta para limitar el tamaño de los archivos a 10 kB
<input type="hidden" name="MAX_FILE_SIZE" value="10240">
El valor precisado en esta zona no puede ser superior al valor de la directiva de configuración...