Home | Clases | Programación en PHP | Campos de entrada y formularios

Campos de entrada y formularios


Introducción

Desde el punto de vista del desarrollador PHP, una página web es, además de una petición HTTP en la que el cliente solicita el acceso a unos recursos específicos, una petición en la que el cliente puede incluir una serie de datos adicionales (request) para personalizar dicha petición o para que sean almacenados en el servidor.

Esta comunicación cliente - servidor se realiza mediante formularios, que pueden utilizar dos métodos HTTP:

  • GET: envío de datos como un query string (cadena de texto dentro de la URL)
  • POST: envío de datos como data payload (carga de datos)


Método GET

Como hemos avanzado, en este caso el envío de información se realiza a través de una cadena de texto que acompaña a la URL de destino. De este modo, mediante GET no es posible enviar archivos de ningún tipo, siendo ésta su principal limitación.

Es el método de envío por defecto si no indicamos ninguno al declarar el formulario.


<form action="index.php" method="GET">
Lista: <input type="text" name="lista"/>
Ordenar por:
<select name="orden">
<option value="nombre">Nombre</option>
<option value="ciudad">Ciudad</option>
<option value="cp">Código Postal</option>
</select>
Sort order:
<select name="direccion">
<option value="asc">Ascendente</option>
<option value="desc">Descendente</option>
</select>
<input type="submit" value="Ver" name="ver"/>
</form>


En el código anterior, al enviar el formulario, se podría generar la siguiente URL:

http://www.ejemplo.com/index.php?lista=usuario&orden=ciudad&direccion=asc


Lo cual nos permitiría recuperar nuestras variables en nuestro script PHP mediante el array superglobal S_GET de la siguiente forma:


$lista = $_GET['lista'];
$orden = $_GET['orden'];
$direccion = $_GET['direccion'];


Como vemos, el proceso es muy sencillo, al enviar el formulario, la URL se construye añadiendo el carácter ? al final de la URL, seguido de las diferentes variables que queramos enviar en forma clave=valor, separadas cada una de ellas mediante el símbolo &.

Ejercicios propuestos

  • Genera un formulario y un script utilizando GET que envíe y recoja nombre de empresa, email y password de un cliente.
  • Prueba ahora a realizar el envío generando tú mismo la URL. ¿Qué pasa con los espacios o las tildes? ¿Y con las @? ¿Y si la empresa se llama M&m's? ¿Qué pasa con la password?
  • Prueba a hacer los mismo que antes, utilizando las funciones url_encode() y url_decode()
  • Prueba a realizar una consulta a Google y a Amazon desde la URL.

Unas últimas consideraciones sobre GET:

  • GET no es más inseguro que POST, ya que este ultimo es fácilmente inyectable por código malicioso si la página no tiene una encriptación básica tipo TLS.
  • Debemos evitar enviar información susceptible a través de GET como password o datos personales
  • Debemos utilizarlo, en general, solo cuando estemos proporcionando información al servidor relativa al contenido que queremos recuperar (orden, página, cantidad, etc.).
  • No debemos utilizarlo cuando estemos enviando información para que sea almacenada en el servidor.
  • GET mejora el SEO de nuestra página web y evita el típico mensaje de error de ¿desea reenviar el formulario?
  • GET proporciona al usuario la capacidad de alterar las consultas en la URL, lo cual puede generar errores para los que nuestro script debe estar preparado.


Método POST

En este caso, los datos se envían de forma "invisible" para el usuario, y es la que debemos utilizar cuando sean datos susceptibles de ser almacenados en el servidor, tales como datos personales, contraseñas, datos bancarios, etc. o cuando necesitemos enviar datos muy largos, ya que la URL tiene una longitud máxima de 2000 caracteres (algo más en ciertos navegadores y estándares, pero se limita a 2000 para asegurar la compatibilidad).

Los datos se recuperarán a través del array superglobal $_POST, de modo que cada elemento del mismo corresponderá a un dato enviado, que puede ser de cualquier tipo: un string, un número o incluso un array. Considerando los siguientes ejemplos:



<form action="index.php" method="POST">
<input type="hidden" name="login" value="1"/>
Usuario: <input type="text" name="usuario"/>
Clave: <input type="password" name="clave"/>
<input type="submit" value="Acceder" name="acceder"/>
</form>


<form action="index.php" method="POST">
<p>Escoge los lenguajes de programación que dominas o pretendes dominar en los próximos 12 meses</p>
<p>
<label><input type="checkbox" name="lenguajes[]" value="PHP"/>PHP</label>
<label><input type="checkbox" name="lenguajes[]" value="JavaScript"/>JavaScript</label>
<label><input type="checkbox" name="lenguajes[]" value="Java"/>Java</label>
<input type="submit" value="Enviar" name="encuesta"/>
</p>
</form>


La forma de recuperar la información de los ejemplos en nuestro script PHP mediante el array superglobal S_POST podría ser:



if (isset($_POST['acceder']) AND $_POST['login'] == 1){
$usuario = $_POST['usuario'];
$clave = $_POST['clave'];
}


if (isset($_POST['encuesta']) AND $_POST['encuesta'] ){
$lenguajes = [];
foreach ($_POST['lenguajes'] as $lenguaje){
array_push($lenguajes, $lenguaje);
}
}


Además, es el único método válido para enviar ficheros de cualquier tipo (imágenes, pdf, texto, etc.), que se recuperarán a través del array superglobal $_FILES que veremos a continuación.

Para finalizar, si nos estamos conectando con algún servicio web y no sabemos a priori cuál es el método con el que nos están enviando los datos ($_GET o $_POST), podemos utilizar el array superglobal $_REQUEST que, en función de la configuración del archivo php.ini, nos permite recuperar los datos de POST, GET y Cookies.

Ejercicio propuesto

  • Modifica el formulario realizado por equipos para que incluya sexo (con radio) e idiomas hablados (con checkbox, 5 opciones más una caja de texto para otros idiomas) y para que se guarden todos los datos en un fichero de texto.



Subida de ficheros

Para poder subir ficheros al servidor mediante formularios debemos utilizar siempre el método POST y recuperar los datos mediante el array superglobal $_FILES.

Si bien es posible subir cualquier archivo a nuestro servidor mediante este método, hay que ser muy cuidadoso a la hora de elegir qué tipos de archivo podemos permitir que sean almacenados (extensiones), así como en qué carpetas (y con qué permisos) se pueden almacenar.

Los ficheros se pueden subir mediante una transacción HTTP POST "multi-part", y un ejemplo básico de formulario para la subida de ficheros sería el siguiente:


<form enctype="multipart/form-data" action="index.php" method="POST">
<input type="file" name="archivo"/>
<input type="submit" value="Subir archivo" name="subir"/>
</form>


Es posible limitar, mediante el archivo de configuración php.ini, diferentes aspectos de la subida, tales como el tamaño, las subidas simultáneas, el tiempo máximo de subida, etc.

Una vez que el archivo es subido al servidor, este se almacena en una ubicación temporal que es accesible por el script PHP, y este será el encargado de trasladarlo a la ubicación definitiva.

De este modo, las archivos subidos estarán almacenados en el array superglobal $_FILES que contendrá, para cada archivo siguiente, un array con los siguientes elementos:

  • name: El nombre original del archivo
  • type: El tipo MIME del fichero proporcionado por el navegador ¿Qué son los tipos MIME?
  • size: El tamaño del archivo (en bytes)
  • tmp_name: El nombre de la ubicación temporal del archivo
  • error: Un código de error asociado al archivo (UPLOAD_ERR_OK indica que se ha subido correctamente, cualquier otro será indicativo de algún fallo)


Con esta información, para terminar de subir el archivo comprobaremos que realmente se ha subido (y que no es un código malicioso que redirecciona a otro sitio, por ejemplo) con la función is_uploaded_file(), y lo trasladaremos a su ubicación definitiva con move_uploaded_file().

Es importante no utilizar el parámetro name como nombre del fichero sin asegurarse antes de que es válido, o bien generar nuestros propios nombres de archivo.

Una forma de recuperar la subida de un fichero en nuestro script PHP según el ejemplo anterior podría ser:


if (isset($_POST['subir'])){
$archivo_recibido = $_FILES['archivo'];
$directorio_subida = '/var/www/uploads/';
$archivo_subido = $directorio_subida . basename($archivo_recibido['name']);

if (is_uploaded_file($archivo_recibido['tmp_name']) AND move_uploaded_file($archivo_recibido['tmp_name'], $fichero_subido)) {
echo "El fichero es válido y se subió con éxito.\n";
} else {
echo "¡Posible ataque de subida de ficheros!\n";
}
}


Ejercicio propuesto

  • Genera un formulario de subida de ficheros que solo acepte imágenes (mediante MIME) y además las almacene en una carpeta del proyecto utilizando como nombre imagen1, imagen2, imagen3, etc.


Filtrado y validación de datos en formularios

No obstante todo lo anterior, PHP recomienda que en vez de acceder a los array superglobal $_GET o $_POST directamente, lo hagamos a través de la función filter_input(), que nos permite filtrar la entrada de modo que evitemos en nuestros formularios ataques de tipo XSS por inyección de código malicioso.

La forma de utilizar esta función sería por ejemplo:


//Vía GET
$nombre = filter_input(INPUT_GET, 'nombre', FILTER_SANITIZE_SPECIAL_CHARS);
/Vía POST
$nombre = filter_input(INPUT_POST, 'nombre', FILTER_SANITIZE_SPECIAL_CHARS);


El tipo de filtrado o saneamiento dependerá del tercer parámetro, del cual se pueden consultar todas las especificaciones AQUÍ.

Ejercicio propuesto

  • Modifica todos los ejercicios anteriores para que incluyan el filtrado o saneamiento más adecuado en cada caso.

Fecha de publicación: 06/09/2019
Asignaturas: desarrollo web en entorno servidor
Temas: php variables bucles arrays
Utilizamos cookies propias y de terceros para mejorar su experiencia en la navegación. Al seguir navegando entendemos que acepta su uso.
Si lo desea, consulte nuestras políticas de privacidad y cookies
ENTENDIDO
[X] Cerrar

Contacta conmigo


[X] Cerrar

Acceso alumnos