Biblioteca Online : ¡La Suscripción ENI por 9,90 € el primer mes!, con el código PRIMER9. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. PHP 7
  3. Gestión de los formularios y los enlaces
Extrait - PHP 7 Desarrollar un sitio web dinámico e interactivo (2ª edición)
Extractos del libro
PHP 7 Desarrollar un sitio web dinámico e interactivo (2ª edición) Volver a la página de compra del libro

Gestión de los formularios y los enlaces

Información general

1. Introducción

En los sitios web dinámicos, muy a menudo es necesario interactuar con el usuario.

En HTML, existen principalmente dos métodos para interactuar con un usuario:

  • los enlaces (etiqueta <a>);

  • los formularios (etiqueta <form>).

Se pueden usar scripts PHP para procesar el clic del usuario en un enlace o la introducción de datos por parte del usuario en un formulario.

2. Los enlaces

El enlace es la técnica básica que permite a un usuario navegar entre las diferentes páginas de un sitio.

Un enlace HTML se define entre las etiquetas <a> y </a>.

Sintaxis simplificada

<a   
 [ href="url" ]  
 [ id="identificador_enlace" ]  
 [ target="destino" ]  
>  
...  
</a> 

Los atributos de la etiqueta <a> son los siguientes:

href

URL (Uniform Resource Locator) relativa o absoluta a la que llama el enlace.

id

Identificador del enlace. Si la página HTML contiene varios enlaces, el identificador permite diferenciarlos. En nuestro caso, este identificador no tiene ningún valor porque no se recupera en el script de procesamiento del enlace. En contraposición, se puede utilizar del lado del cliente, en JavaScript, por ejemplo.

target

Destino (por ejemplo, otra ventana) en el que se abrirá la dirección URL de destino. Por defecto, la URL de destino se muestra en la misma ventana.

La URL puede contener parámetros que permitan pasar información de una página a otra.

Sintaxis

url_clasica?nombre=valor[&...] 

El signo de interrogación (?) introduce la lista de parámetros de URL separados por el carácter "&"; cada parámetro se compone de un nombre/valor en la forma nombre=valor:

www.misitio.com/info/inicio.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" /><title>Página 1</title></head>  
 <body>  
   <div>  
   <!-- enlace hacia...

Recuperar los datos pasados por la URL

1. Consideraciones

a. ¿Qué sucede si dos parámetros comparten el mismo nombre?

Simplemente, el último parámetro encontrado en la URL es el que determina el valor.

Ejemplo

<a href="pagina2.php?nombre=Olivier&nombre=Xavier">Página 2</a> 

Esta URL da una sola variable nombre igual a Xavier en la matriz $_GET.

b. Utilizar una matriz para pasar datos en la URL

Es posible utilizar una notación del tipo matriz en el nombre del parámetro que se pasa en la URL.

Ejemplo

<a href="pagina2.php?data[]=HEURTEL&data[]=Olivier">Página 2</a> 

Esta URL da una variable data, de tipo matriz, que contiene las siguientes líneas:

Clave

Valor

0

HEURTEL

1

Olivier

PHP completa la matriz 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 - Matrices).

Esta técnica es interesante, pero en el código debe saber que el índice 0 corresponde al apellido y el índice 1 al nombre. Por otra parte, puede surgir un problema si el orden de los parámetros cambia.

Para mejorar esta técnica, es posible establecer la clave, bien con un número o con una cadena de caracteres.

Ejemplo

<a href="pagina2.php?data[apellido]=HEURTEL&data[nombre]=Olivier"> 
Página 2</a> 

Esta URL da el resultado siguiente en la matriz data:

Clave

Valor

apellido

HEURTEL

nombre

Olivier

2. Transferir caracteres especiales

Si el valor que se transmite no contiene caracteres especiales (espacio, signo &, signo de interrogación (?), etc.), puede colocarse directamente en la URL como se ha indicado anteriormente. De lo contrario, es necesario codificarla para evitar la interpretación incorrecta de estos caracteres especiales.

Por ejemplo, si el dato pasado en la URL contiene "Olivier & Xavier", solo "Olivier" se recuperará a su llegada, ya que el & se interpreta como el separador de parámetros.

La codificación necesaria se puede realizar muy fácilmente con las funciones urlencode o rawurlencode.

Sintaxis

cadena urlencode(cadena valor)  
cadena rawurlencode(cadena valor) 

valor

Cadena que se va a codificar.

Estas dos funciones devuelven...

Recuperar los datos introducidos en el formulario

1. Consideraciones

a. ¿Qué sucede si dos campos comparten el mismo nombre?

Simplemente, el último campo encontrado en el formulario es el que determina el valor. 

Ejemplo

<form action="entrada.php" method="POST"><div>  
Apellido: <input type="text" name="nombre"><br />  
Nombre: <input type="text" name="nombre"><br />  
<input type="submit" name="ok" value="OK">  
</div></form> 

El texto HEURTEL en la primera zona y Olivier en la segunda dan un solo valor igual a Olivier en la matriz $_POST.

b. ¿Qué ocurre si hay dos formularios en la página HTML?

Las variables solo se crean y se rellenan en el formulario que ha sido validado.

Ejemplo

<form action="entrada.php" method="POST"><div>  
Nombre 1: <input type="text" name="nombre1"><br />  
<input type="submit" name="ok1" value="OK1">  
</div></form>  
<form action="entrada.php" method="POST"><div>  
Nombre 2: <input type="text" name="nombre2"><br />  
<input type="submit" name="ok2" value="OK2">  
</div></form> 

Si el usuario valida el primer formulario, el valor nombre1 estará disponible. Si el usuario valida el segundo formulario, el valor nombre2 estará disponible.

c. Usar una matriz para recuperar los datos introducidos

Es posible utilizar una notación de tipo matriz en el atributo name de las etiquetas <input>, <select> y <textarea>.

Ejemplo

<form action="entrada.php" method="POST"><div>  
Apellido: <input type="text" name="entrada[]"><br />  
Nombre: <input type="text" name="entrada[]"><br />  
<input type="submit" name="ok" value="OK">  
</div></form> 

El texto HEURTEL en el primer campo y Olivier en el segundo dan una sola variable $entrada, de tipo de matriz, que contiene las líneas siguientes:

Clave

Valor

0

HEURTEL...

Controlar los datos recuperados

1. Información general

En la primera parte de este capítulo, vimos cómo recuperar los datos pasados en una URL o introducidos en un formulario.

A continuación, es necesario comprobar que los datos recuperados son correctos, es decir, que respetan las normas de gestión definidas para la aplicación.

Para la seguridad del sitio, es necesario no fiarse de los datos procedentes del exterior (formulario, URL, pero esto también lo veremos más adelante: cookie, etc.). Estos datos se deben controlar, filtrar, para evitar posibles ataques de un usuario malintencionado.

El objetivo de este apartado es proporcionar una orientación sobre las técnicas más utilizadas en PHP para realizar esta comprobación. Otro posible enfoque consiste en realizar un control en JavaScript en el navegador; se trata de evitar un viaje de ida y vuelta al servidor.

Los diferentes ejemplos que se presentan en esta parte utilizan formularios. Deben realizarse las mismas verificaciones para los datos pasados en una URL.

2. Comprobaciones clásicas

a. Limpieza de los espacios no deseados

La función trim (véase el capítulo Utilizar las funciones PHP - sección Manipular las cadenas de caracteres) se puede utilizar para eliminar los espacios en blanco no deseados al principio o al final de la cadena. En el caso de un formulario, este procesamiento se aplica especialmente a los campos de entrada libre (<input> de tipo text o password, <textarea>).

Ejemplo

// Recuperar el valor introducido en el campo "apellido" y limpiar 
// los espacios en blanco (al principio y al final) 
$apellido = trim($_POST['apellido']); 

b. Datos obligatorios

Comprobar si un dato obligatorio está presente resulta muy simple: basta con comprobar si la variable asociada contiene un valor.

Ejemplo

$apellido = trim($_POST['apellido']); 
if ($apellido == '') { 
 // $apellido vacío = campo "apellido" no rellenado => hacer algo 
} 

c. Longitud máxima de una cadena

La longitud de los datos recuperados se puede controlar con la función strlen (véase el capítulo Utilizar las funciones PHP - sección Manipular las cadenas de caracteres). En el caso de un formulario, este procesamiento se aplica especialmente a los campos de entrada libre...

Problemas con los datos recuperados

Puede producirse un problema de presentación en un campo de formulario si el texto que se muestra contiene un signo de comillas (").

Ejemplo

images/07ri20.png
images/07ri21.png

Código fuente de la página en el navegador (extracto)

   <form action="entrada.php" method="post"> 
   <div> 
     Entrada: <input type="text" name="entrada" 
               value="dijo: "¡Hola!"" /> 
     <input type="submit" name="ok" value="OK" /> 
     <br />dijo: "¡Hola!"    </div> 
   </form> 

En HTML, en los atributos de las etiquetas (value, name...), el delimitador de cadena es el signo de comillas. En el atributo value, la secuencia "dijo:" se considera como el valor del atributo y el resto de la cadena se pasa por alto. El problema se produce incluso si las comillas se escapan por medio del carácter \ porque este último no es un carácter de escape en HTML.

Otro problema de presentación se produce en la página si los datos mostrados contienen etiquetas HTML.

Ejemplo

images/07ri22.png

El fragmento Olivier <b>Heurtel da la palabra Heurtel en negrita cuando se visualiza en la página HTML. La secuencia <b> introducida por el usuario se encuentra tal cual en el código fuente de la página y, por lo tanto, se interpreta por el navegador como la etiqueta de la negrita.

Por último, podemos encontrarnos con un tercer problema al escribir en un campo de comentario.

Ejemplo

images/07ri23.png

Un texto de varias líneas en el campo <textarea> se vuelve a mostrar tal cual en el campo, pero aparece 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 campo <textarea> no es interpretado por el navegador: es necesario incorporar una etiqueta <br />.

Por tanto, vemos que aparecen tres problemas relativos a la presentación en la página HTML de los datos introducidos por el usuario:

  • La presencia del carácter de comillas, que puede suponer un problema cuando se usan los datos en un formulario (atributo value).

  • La presencia...

Utilización de filtros

1. Principios

Esta extensión permite filtrar y validar los datos, incluidos los introducidos por los usuarios.

Cada filtro está definido por un número (identificador), un nombre y posibles opciones y los indicadores que definen el comportamiento del filtro. Cada opción está definida por un nombre que se utiliza como clave en una matriz asociativa. Cada indicador se define por una constante; para especificar varios indicadores, basta con sumar las constantes correspondientes.

Algunos ejemplos de ellos filtros (véase la documentación para la descripción de todos): 

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 punto flotante.

FILTER_VALIDATE_REGEXP

Valida un valor utilizando una expresión regular compatible con PERL. La expresión regular que se va a utilizar se especifica con la opción regexp.

FILTER_VALIDATE_EMAIL

Valida un valor como dirección de correo electrónico.

FILTER_SANITIZE_STRING

Elimina las etiquetas contenidas en una cadena y codifica los caracteres ’ y ". Hay disponibles varios indicadores para eliminar o codificar caracteres adicionales (más adelante).

FILTER_SANITIZE_SPECIAL_CHARS

Codifica en HTML los caracteres ’, ", <, > y &, así como todos los caracteres de código ASCII inferior a 32. Hay disponibles varios indicadores para eliminar o codificar caracteres adicionales (véase más adelante).

Los siguientes indicadores se pueden utilizar con los filtros FILTER_SANITIZE_STRING y FILTER_SANITIZE_SPECIAL_CHARS:

FILTER_FLAG_STRIP_LOW

Elimina los caracteres de código ASCII por debajo de 32.

FILTER_FLAG_STRIP_HIGH

Elimina los caracteres de código ASCII por encima de 127.

FILTER_FLAG_ENCODE_HIGH

Codifica en HTML los caracteres de código ASCII por encima de 127.

Además, los siguientes indicadores se pueden utilizar con el filtro FILTER_SANITIZE_STRING:

FILTER_FLAG_NO_ENCODE_QUOTES

No codifica los caracteres ’ ni ".

FILTER_FLAG_ENCODE_AMP

Codifica en HTML el carácter &.

FILTER_FLAG_ENCODE_LOW

Codifica en HTML los caracteres de código ASCII por debajo de 32.

Por otra parte, el indicador FILTER_NULL_ON_FAILURE...

Ir a otra página

En el procesamiento efectuado por un script PHP, puede ser necesario mostrar otra página. 

El caso puede producirse, por ejemplo, al final del procesamiento de un formulario; la situación puede variar en función de si el formulario se procesa por el script que lo muestra o por un script independiente.

Variantes posibles

images/07ri32a.png

Es posible redirigir al usuario a otra página desde el 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 solititud a otra dirección.

Sintaxis de la directiva location

location: URL absoluta o relativa 

Sintaxis con la función header

header('location: URL absoluta o relativa') 

Ejemplos

// Redirección a un script PHP situado al mismo nivel. 
header('location: error.php'); 
// Redirección hacia una página HTML situada en un subnivel. 
header('location: ./error/entrada.htm'); 
// Redirección hacia otro sitio. 
header('location: http://www.olivier-heurtel.es'); 

El protocolo HTTP 1.1 requiere una URL absoluta en la directiva location. Para ello, puede utilizar las variables globales $_SERVER[’HTTP_HOST’] y $_SERVER[’PHP_SELF’] (véase capítulo Anexo - sección 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 />'; 
$url_absoluta = 'http://' . $_SERVER['HTTP_HOST'] . 
              rtrim(dirname($_SERVER['PHP_SELF']), '/\\') . 
              '/' . $url_relativa; 
echo '$url_absoluta = ',$url_absoluta,'<br />'; 
?> 

Resultado...

Intercambiar un archivo entre el cliente y el servidor

1. Resumen general

Algunos sitios pueden ofrecer a los usuarios cargar documentos desde su equipo al servidor web: enviar un currículum vitae en un sitio (sitio de búsqueda de empleo), adjuntar un archivo en un mensaje (sitio de mensajería) o, simplemente, guardar el documento en el servidor (sitio de almacenamiento).

En la terminología anglosajona, esta característica se llama "file upload".

Por el contrario, muchos sitios permiten a los usuarios descargar ("download") documentos desde el servidor web a su equipo.

Estas dos características son aplicaciones específicas de las técnicas que se presentan en este capítulo.

2. Enviar un archivo desde el cliente (upload)

Esta característica es muy fácil de implementar en PHP y necesita dos operaciones:

  • En un formulario, proporcionar un campo en el que el usuario pueda 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.

En la primera parte de este capítulo hemos visto la posibilidad de disponer en un formulario un campo que permita indicar la ubicación de un archivo en su equipo (type="file").

Pero colocar una zona de este tipo no es suficiente. Para provocar la transferencia del archivo, basta con añadir el atributo enctype="multipart/form-data" en la etiqueta <form>:

<form action="entrada.php" method="post"  
   enctype="multipart/form-data"> 

Esta técnica funciona solo con los formularios que utilizan el método POST.

Además, es posible añadir un campo oculto en el formulario para limitar el tamaño de los archivos que se pueden enviar al servidor. Este campo oculto, obligatoriamente situado antes del campo de tipo file, debe llamarse MAX_FILE_SIZE (atributo name) y especificar el tamaño máximo en bytes 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 especificado en esta zona no puede superar el valor de la directiva de configuración upload_max_filesize (2 MB por defecto). Si la zona oculta no está presente, se aplica el tamaño especificado...