Verificar tipos de archivos subidos al servidor con php

Los formularios HTML son puntos de entrada a nuestra aplicación Web, y por lo tanto a nuestro servidor. Una persona malintencionada podría utilizar los elementos de nuestros formularios para almacenar contenido peligroso en nuestra base de datos, o en forma de fichero en algún directorio.

El formulario nos permite especificar cuál es el método HTTP utilizado para enviar los datos del formulario al servidor, utilizando el atributo method. Si deseamos subir un archivo será necesario indicar como método POST (aunque algunos navegadores también admiten PUT).

Para subir archivos debemos incluir en el formulario HTML un elemento <input> de tipo “file” (con el atributo type=”file”). Un ejemplo de formulario sería:

El elemento “input file” nos permite seleccionar un archivo cualquiera de nuestro equipo (desde el equipo al que accedemos al formulario). Al hacer clic sobre el botón “submit” el navegador enviará al servidor el contenido de nuestro formulario, incluyendo el archivo seleccionado.

Aunque el atributo “accept” no debería utilizarse como instrumento para validar el tipo de archivo, sí es interesante añadirlo, ya que los buscadores (Firefox, Chrome, IE, …) pueden hacer uso de él para ofrecer un interfaz de usuario más apropiado, en función del tipo de archivo a seleccionar. Así por ejemplo, si añadimos el valor “image/jpeg“, como es nuestro ejemplo, el navegador podría ofrecer al usuario la posibilidad de obtener la imagen de la cámara local o seleccionarla de su colección de fotos.

El script que recibe el formulario es, en nuestro ejemplo, guardar_archivo.php, el especificado por el atributo action del elemento <form>.

En este archivo php puede programar la validación del formulario (¿contiene el formulario los datos esperados?), así como el almacenamiento del archivo.

En PHP, para acceder al archivo subido, en el script guardar_archivo.php, utilizaremos la variable superglobal $_FILES, un array asociativo en el que encontraremos la información que necesitamos para validar el fichero y almacenarlo. Accederemos a esta información utilizando como índice el nombre que le dimos al elemento input de tipo file, en nuestro caso $_FILES[‘mi_archivo’]. Así por ejemplo:

  • En $_FILES[‘mi_archivo’][‘error’], obtendremos el valor 0 si el archivo se subió correctamente, o mayor que cero si hubo error.
  • En $_FILES[‘size’] el tamaño del fichero en número de bytes.
  • En $_FILES[‘tmp_name’] la ruta en la que temporalmente se ha almacenado el fichero subido.

Los códigos de error que puede devolver $_FILES[‘mi_archivo’][‘error’] son:

  • 1 → El fichero seleccionado excede el tamaño máximo permitido en php.ini (podemos saber el tamaño máximo permitido usando la función ini_get(‘upload_max_filesize’)).
  • 2 → El archivo subido excede la directiva MAX_FILE_SIZE, si se especificó en el formulario.
  • 3 → El archivo subido fue sólo parcialmente cargado.
  • 4 → No se ha subido ningún archivo.
  • 6 → Falta el directorio de almacenamiento temporal.
  • 7 → No se puede escribir el archivo (posible problema relacionado con los permisos de escritura).

En el siguiente enlace podemos encontrar detalles sobre estos códigos de error, y ejemplos sobre su tratamiento:
http://es2.php.net/manual/es/features.file-upload.errors.php

En el siguiente enlace hay un ejemplo sobre como especificar MAX_FILE_SIZE en el formulario:
http://php.net/manual/es/features.file-upload.post-method.php

Si no se ha producido ningún error, y no hemos especificado MAX_FILE_SIZE en el formulario, podríamos comprobar que el tamaño del archivo no supera un determinado límite, por ejemplo así:

Llegado a este punto, sólo nos queda validar el tipo de archivo, que después de todo era el objetivo de este artículo.

Validando el Tipo de Archivo:

Vamos a suponer que queremos subir archivos gráficos, cuyo formato sea png o jpg. Si se intenta subir cualquier otro tipo de archivo, devolveremos un mensaje de error.

Validando un archivo gráfico:

La ruta al archivo subido temporalmente al servidor la proporciona $_FILES[“filelogo”][“tmp_name”]. Conociendo la ruta utilizaremos la función de PHP exif_imagetype para determinar el tipo:

Si el formato es el correcto podríamos pasar a validar las dimensiones del archivo gráfico. Por ejemplo, supongamos que deben ser exactamente 150 píxeles de alto y ancho:

About the author

Pablo Blanco

Llevo 15 años dedicado al desarrollo de software de forma profesional. También ha trabajado como profesor técnico de F.P.en ciclos formativos de informática.
Títulado en Ingeniería T. Informática y Diplomado en CC. Empresariales.

4 Comments

Leave a comment
  • buenos dias me parece muy interesante el codigo queria pedirles ayuda de como actualizar un imagen la inserccion funciona correctamente ahora lo que necesito es saber comoa atualizarlo ya que me sale un error archivo no permitido, es tipo de archivo prohibido o excede el tamano de $limite_kb Kilobytes espero me puedan ayudar

  • Hola Pablo,

    Explique un poco mejor su problema por favor, sino será difícil que le podamos ayudar.
    Dice que la insercción funciona … ¿la insercción en dónde? Se refiere a que guarda el archivo correctamente en el servidor, en una base de datos …. ?
    Cuando habla de actualizar, qué tipo de operación está realizando, que funciones utiliza, …
    ¿Cuál es exactamente el mensaje de error?
    La variable $limite_kb, ¿la ha declarado usted, dónde la usa, cómo … ?

    Un saludo!

  • Buenas tardes, estoy desarrollando un proyecto en el cual debo capturar una imagen o foto desde una camara web con un boton, el caso es que no doy con como subir la imagen a una carpeta local de mi servidor php (fotos) y guardar la ruta en mysql… Agradezco su pronta ayuda

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

*

Copyright © 2014. Pablo Blanco.