Cómo subir imagenes con formularios HTML y PHP

Aprende a subir imagenes con un formulario HTML y almarcenarlas con php en el servidor.

php y html Ficheros en php Programacion web

A menudo, cuando desarrollamos aplicaciones web, es necesaria la posibilidad de subir ficheros o imagenes al servidor, ya seamos nosotros como webmasters, usuarios autorizados o parte del público general de la web.

La forma exacta de resolver el problema dependerá del lugar donde necesitemos autorizar este uso de la web, en la que siempre tendremos que tener en cuenta los posibles agujeros de seguridad que podemos crear. No será lo mismo programar una subida de fotos 

En este tutorial voy a tratar cómo subir imágenes con formularios y también cómo subir imagenes en PHP, con un filtrado básico de tipos de fichero (sus extensiones), y el guardado de estos ficheros en el servidor. También comentaré algunos trucos sencillos para incrementar la seguridad de nuestro desarrollo.

Detalladamente en este artículo encontrarás explicados los siguientes conceptos:

  1. Bases para entender cómo subir ficheros con html y php.
  2. Pasos para subir imágenes con html.
  3. Formulario HTML de ejemplo para subir cualquier tipo de archivo.
  4. Explicación de etiqueta input especial para subir ficheros.
  5. Comprobaciones de seguridad sobre los ficheros subidos.
  6. Cómo mover un fichero subido a la carpeta deseada.
  7. Cómo mostrar las imágenes subidas al servidor con el formulario.

Bases para subir ficheros en una web

Para habilitar la subida de los ficheros en nuestra web deberemos de conocer el lenguaje de marcas HTML y el lenguaje de programación web PHP. Por la parte de HTML vamos a necesitar un formulario HTML, y en php necesitaremos conocer el uso de funciones y conocimientos básicos de rutas de ficheros.

  • Nuestro código HTML (el formulario) se encargará de mostrar las opciones correspondientes en el navegador del usuario para que vea un explorador de ficheros de su equipo (pc o móvil) y la opción de adjuntar su selección.
  • En la programación del lado del servidor, mediante php, comprobaremos que tipo de fichero nos han subido, su tamaño, y en caso que creamos correcto, lo guardaremos en una carpeta para evitar que se pierda como un archivo temporal

Pasos para poder subir imagenes con html

Para permitir que los usuarios suban imagenes o ficheros mediante HTML vamos a utilizar:

  • Un formulario HTML configurado apropiadamente.
  • Un INPUT HTML específico para adjuntar ficheros en html.
  • Un botón submit que nos permita confirmar el envío del formulario.

El formulario html para subida de ficheros

Los formularios, configurados de forma adecuada, permitirán adjuntar un fichero/imagen o varios y, encriptados, enviarlos al servidor mediante protocolo http. El resultado será un formulario para subir imagenes php.

Son dos atributos del formulario los que darán acceso a la posibilidad de subir ficheros:

  1. El atributo method que indica la forma de envío de los datos al servidor (GET o POST).
  2. El atributo enctype. El tipo de encriptación de la información. Por defecto x-www-urlencoded.

La etiqueta de nuestro formulario quedaría así:

<form name="subida-imagenes" type="POST" enctype="multipart/formdata" >

Como puedes ver, a parte del nombre que es básico para que el formulario funcione, he indicado en el tipo de formulario (type) el envío de datos mediante POST, y la encriptación de la información (enctype), requerida para que un fichero pueda ser adjunto, como multipart/formdata.

La configuración multipart/formdata indica que la información del formulario se enviará por paquetes a través de la red.

Etiqueta html para adjuntar fichero

Ahora que nuestra etiqueta de formulario está lista, vamos a introducir la etiqueta de formulario especial para ficheros, un input muy similar a los demás:

<form name="subida-imagenes" type="POST" enctype="multipart/formdata" >
	<input type="file" name="imagen" />
</form>

Esta etiqueta input se autoconfigurará para subir ficheros tan solo indicando file en el atributo type. Los navegadores identificarán inmediatamente este atributo y mostrarán gráficamente un botón para seleccionar archivos del sistema.

Por último añadiremos un botón de tipo submit para poder confirmar el envío del formulario al servidor.

<form name="subida-imagenes" type="POST" enctype="multipart/formdata" >
	<input type="file" name="imagen1" />
	<input type="submit" name="subir-imagen" value="Enviar imagen" />
</form>

Tratado de ficheros subidos con php

Una vez los usuarios de nuestro formulario confirmen el envío, en el servidor, en nuestra programación habitual de tratamiento de los datos enviados, tendremos acceso al fichero o ficheros que hayan adjuntado. Pero así como por norma general tenemos acceso a los datos recibidos mediante la variable superglobal $_POST o $_GET según el método del formulario, el acceso a ficheros será mediante el array también superglobal $_FILES.

Veamos de que información disponemos en el array $_FILES para una imagen llamada 'saludo.jpg' subida mediante nuestro formulario:

<?php
echo $_FILES['imagen1']['name'];
echo $_FILES['imagen1']['tmp_name'];
echo $_FILES['imagen1']['type'];
echo $_FILES['imagen1']['size'];
echo $_FILES['imagen1']['error'];
?>

Mediante estos echo's he accedido a toda la información disponible del fichero en PHP. La información impresa sería la siguiente:

saludo
213mnuashduahs0923
image/jpg
120304
0

Respectivamente estos valores del primero al último representan la siguiente información:

  1. Nombre del fichero subido.
  2. Nombre temporal asignado al fichero por el servidor. Este nombre es único y permite identificarlo dentro de la carpeta de temporales.
  3. Tipo MIME de fichero subido: jpg, png, gif, pdf, etc.
  4. Tamaño en bytes del fichero, si quisieramos calcular el tamaño a kilobytes deberíamos dividir entre 1024 y para pasar a megabytes volver a dividirlo entre 1024.
  5. Código de error de la subida, en nuestro caso 0 o UPLOAD_ERR_OK que indica que no se ha producido error alguno. Códigos de error subida de fichero.

Filtrado con php de tipos de ficheros subidos con html

Una vez sabemos como acceder a la información de los ficheros subidos, voy a centrarme en el filtrado de los tipos de ficheros aceptados. Limitar el tipo de fichero subido es altamente recomendable para evitar posibles problemas de seguridad.

Para este ejemplo voy comprobar que la imagen súbida sea en efecto una imagen con una de las extensiones más comunes y que su tamaño sea menor a 1 MB:

<?php
$extensiones = array(0=>'image/jpg',1=>'image/jpeg',2=>'image/png');
$max_tamanyo = 1024 * 1024 * 8;
if ( in_array($_FILES['imagen1']['type'], $extensiones) ) {
     echo 'Es una imagen';
     if ( $_FILES['imagen1']['size']< $max_tamanyo ) {
          echo 'Pesa menos de 1 MB';
     }
}
?>

Escritura de imagenes en carpeta del servidor

Una vez tengamos nuestros ficheros filtrados vamos a proceder a guardarlos de forma permanente en una carpeta de nuestro servidor.

Las imagenes o ficheros subidos mediante los formularios HTML son almacenados siempre en una carpeta temporal del sistema, por lo tanto deberemos moverlos para poder guardarlos permanentemente.

Para trasladar los ficheros de la carpeta temporal directamente a nuestra carpeta elegida usaremos la funcion move_uploaded_file( origen, destino ).

El siguiente ejemplo sería un script alojado en la carpeta raiz de nuestra web, podría ser nuestro index.php:

<?php
$ruta_indexphp = dirname(realpath(__FILE__));
$ruta_fichero_origen = $_FILES['imagen1']['tmp_name'];
$ruta_nuevo_destino = $ruta_indexphp . '/imagenes/' . $_FILES['imagen1']['name'];
if ( in_array($_FILES['imagen1']['type'], $extensiones) ) {
     echo 'Es una imagen';
     if ( $_FILES['imagen1']['size']< $max_tamanyo ) {
          echo 'Pesa menos de 1 MB';
          if( move_uploaded_file ( $ruta_fichero_origen, $ruta_nuevo_destino ) ) {
               echo 'Fichero guardado con éxito';
          }
     }
}
?>

Para mayor claridad he asignado las rutas que intervienen en el proceso a dos variables:

  • El nombre temporal del fichero subido, que se encuentra en la carpeta de temporales, en $ruta_fichero_origen.
  • La ruta completa de destino del fichero, que se compone por una parte de la ruta raiz del script donde estoy trabajando (estoy programando en index.php) más el nombre de la carpeta que he creado para guardar las imagenes (/imagenes) y por último el nombre definitivo que tendrá el fichero (el nombre original del fichero).

Seguridad de escritura de imagenes en carpeta del servidor

Al guardar los archivos subidos por los usuarios en nuestro servidor, puede ocurrir que no filtremos los ficheros introducidos, o guardemos ficheros susceptibles de provocar problemas de seguridad. Para evitar problemas de este tipo lo mejor será incluir en la carpeta donde los almacenamos un pequeño script htaccess que evite la ejecución de código:

RemoveHandler .phtml .php3 .php .pl .py .jsp .asp .htm .shtml .sh .cgi .dat
RemoveType .phtml .php3 .php .pl .py .jsp .asp .htm .shtml .sh .cgi .dat

Con estas dos líneas en un fichero con extensión .htaccess evitaremos una posible ejecución de código por parte de usuarios malintencionados. Recuerda que debes incluir este fichero en la misma carpeta donde almacenas los ficheros.

 

Y ya está, con esto tendrías terminado un formulario para subir imagenes con php totalmente funcional, con comprobaciones de seguridad para evitar subidas de ficheros inesperadas que puedan provocar problemas o hackeos inesperados.

Extra: Mostrar imagenes subidas con html

Mostrar las imagenes guardadas en nuestra carpeta de almacenamiento es sencillo, tan solo deberemos incluir la ruta hasta el fichero en una etiqueta IMG html:

<img src="imagenes/nombre_imagen.jpg" />

Extra: Descarga de ficheros subidos con html

Si lo que queremos es incluir un enlace de descarga para el fichero almacenado en vez de utilizar una etiqueta IMG usaremos una etiqueta para enlaces A, e incluiremos en el atributo HREF la ruta al fichero:

<a href="imagenes/nombre_imagen.jpg"> Descarga de la imagen </a>

Este enlace producirá que el usuario descargue el fichero en cuestión, no obstante si el archivo es por ejemplo una imagen o pdf, el usuario en vez de lograr una descarga directa visualizará el contenido, teniendo que descargarlo haciendo uso de la opción descargar del menú desplegable con clic derecho.

Evitar la visualización de ficheros es posible gracias a HTML5 y los navegadores más modernos: chrome, firefox, opera. Deberemos incluir el atributo DOWNLOAD en la etiqueta de enlace anterior (A), así, el enlace final para una descarga forzada quedaría así:

<a href="imagenes/nombre_imagen.jpg" download="nombre_imagen"> Descarga de la imagen </a>

Sobre el autor

Javier Gómez Redactor en Srcodigofuente.es

Javier Gómez

Ingeniero técnico en informática de gestión. Desarrollador web freelance y profesor de desarrollo web a partes iguales. Testarudo autodidacta, creativo, perfeccionista y alma libre.

Cargando comentarios

Utilizamos "cookies" para información estadística. Si continúas navegando aceptas su uso.