Subir archivos a un servidor desde nuestra web
Permitir que los usuarios de nuestra web puedan enviar archivos directamente al servidor es una utilidad muy versátil que puede ser clave en multitud de procesos.
Algunas de las funcionalidades que podemos implementar gracias a la subida de ficheros por parte de los usuarios son:
EJEMPLO: Gestor de productos de una tienda online.
Envío de imágenes al servidor
Un usuario quiere cambiar la foto de perfil en una red social.
Para ello deberá enviar un archivo .jpg al servidor que la almacenará para poder mostrarla en la web.
Del mismo modo que los parámetros GET y POST son un fundamento básico de la web 2.0, ya que permiten al usuario la creación de contenido, la subida de archivos, al ser un suministro de información por parte de los usuarios a la web, también lo es.
Redes sociales como Facebook, Instagram o YouTube, entre muchas otras, no podrían existir sin la posibilidad de que el usuario subiese archivos.
La subida de archivos, no es una característica exclusiva de PHP, todos los lenguajes de programación web dispondrán de métodos para tratar las subidas de archivos.
La forma de envío de archivos desde el lado del cliente, será idéntica indiferentemente del lenguaje que usemos en el servidor. Si aprendemos un lenguaje de programación web distinto a PHP, simplemente deberemos aprender cómo recuperar los archivos enviados.
Formulario de envío de archivos
Como sucede con en envío de parámetros, para que un usuario pueda subir archivos al servidor, necesitamos crear un formulario HTML en nuestra página web.
Este formulario tiene que contar con tres requisitos para que se pueda realizar el envío de archivos:
Su apariencia por pantalla es similar a la siguiente:
Este tipo de campo, permitirá al usuario seleccionar un archivo de su ordenador o dispositivo.
Para el envío de archivos, evidentemente debemos tener al menos un campo de este tipo.
Al indicar este atributo, establecemos que el campo de tipo file, debe enviar el archivo al servidor. Si no lo establecemos, enviará únicamente el nombre del archivo y no podremos recuperar su contenido.
Vamos a ver un ejemplo completo de formulario de envío de archivos:
Recuperación y tratamiento del archivo enviado
Una vez que el usuario ha enviado el archivo al servidor, utilizaremos un array especial de PHP para recuperar el archivo y su información. Su sintaxis es la siguiente:
Este array es multidimensional y tiene varias componentes con información del archivo:
Nombre del archivo enviado. | |
Ruta temporal donde se ha almacenado el archivo. | |
Tipo MIMESon convenciones dirigidas al intercambio a través de Internet de todo tipo de archivos. Mediante una serie de cadenas de texto estandarizadas, especifican de qué tipo es un archivo determinado. del archivo. Lo utilizaremos para identificar el tipo del archivo. | |
Tamaño en bytes del archivo. |
print_r de $_FILES
Si hacemos un print_r de $_FILES tras el envío de un archivo, nos encontraremos una estructura como la siguiente:
Por defecto, el archivo se sube a un directorio temporal, pero es muy frecuente que queramos guardar este archivo de forma permanente. Para ello utilizaremos la siguiente sintaxis:
será la ruta donde se guardará el archivo. Podemos utilizar tanto rutas relativas (partiendo del directorio en el que se encuentra el script de PHP) como absolutas.
Limitaciones en la subida de archivos
Ya que el usuario podría subir archivos de gran tamaño, haciendo que nuestro servidor se colapsase si no dispone de los recursos adecuados, existen varios parámetros de configuración de PHP que limitan el tamaño y el tiempo de subida.
Podemos modificar los valores de estos parámetros desde nuestro php.ini.
max_file_uploads | 20 | Número máximo de ficheros que se pueden subir de forma simultánea. |
upload_max_filesize | 2M | Tamaño máximo de cada fichero subido. |
post_max_size | 8M | Tamaño máximo del conjunto de datos enviados mediante POST. |
max_input_time | 60 | Tiempo máximo en segundos de envío de datos al servidor. |
Aspectos de seguridad
Debemos tener especial cuidado a la hora de gestionar los archivos que un usuario sube a nuestro servidor. Si permitimos que los usuarios suban cualquier tipo de archivo al servidor, podrían hacernos llegar archivos ejecutables con virus o códigos malintencionados.
Si necesitásemos guardar archivos de este tipo, siempre debemos hacerlo en una carpeta que no sea pública, ya que de lo contrario, el usuario podría lanzar la ejecución de cualquier programa.
Ataque clásico mediante envío de archivos
- Tenemos un formulario en nuestra web http://www.example.com/ con una subida de archivos.
- Un usuario nos envía un archivo llamado hack.php y nosotros lo guardamos en la carpeta pública "archivos".
- El usuario llama a la siguiente dirección http://www.example.com/archivos/hack.php y ejecuta todas las instrucciones de PHP contenidas en él.
- El archivo PHP lee el contenido de todos nuestros archivos PHP y muestra el código por pantalla exponiendo la contraseña de nuestra base de datos.
- El usuario puede acceder ahora a nuestra base de datos y recuperar o modificar toda la información que desee.
Al ejecutar un código PHP, el usuario puede realizar cualquier acción, pudiendo incluso borrar o modificar nuestro código fuente.
Por lo tanto, las precauciones que siempre deberemos tomar a la hora de hacer una subida de archivos son:
EJEMPLO: Si el usuario va a subir una imagen, solo permitiremos archivos con extensión .jpg, .jpeg, .gif o .png
EJEMPLO: Creamos una carpeta al lado de la carpeta pública (carpeta htdocs en XAMPP) llamado archivos y referenciamos las rutas de move_uploaded_file a dicha carpeta.