Archivos en la nube con software escrito en PHP

Software gestor de archivos en la nube con PHP y MySQL

En este post te mostraré un sistema que acabo de crear. Se trata de un software para el alojamiento de archivos en la nube usando PHP y MySQL. Es decir, algo como un Google Drive, Dropbox o Mega pero de forma básica.

Archivos en la nube con software escrito en PHP
Archivos en la nube con software escrito en PHP

Gracias a este software open source de archivos en la nube podemos montar nuestro propio disco en la nube en la red local o en internet, subir archivos y acceder a ellos desde cualquier dispositivo, pues este programa es responsivo.

También podremos compartir los archivos para su descarga, usando un hash único que podemos eliminar más tarde.

A través de este post te mostraré los módulos del programa, explicaré un poco la arquitectura y te enseñaré cómo descargarlo e instalarlo.

Arquitectura del sistema

Esqueleto de software para gestión de archivos en la nube con PHP y Vue
Esqueleto de software para gestión de archivos en la nube con PHP y Vue

Esta aplicación web se divide en dos partes. Tenemos la parte del servidor que está con PHP y MySQL, y la parte del cliente con Buefy, que es una combinación de Vue y Bulma.

Los archivos del servidor, incluyendo dependencias y los archivos que se suben están en api. Aquí tenemos los archivos que sirven como puente, así como los archivos que gestionan toda la aplicación.

Para los archivos del lado del cliente tenemos la carpeta frontend en donde están todos los componentes de Vue, pues se usa la Vue CLI para compilar los archivos e iniciar el servidor de desarrollo.

Ya para pasar a producción simplemente compilamos la app del lado del cliente y copiamos todos sus archivos junto con la carpeta api al servidor en donde vamos a desplegar la app.

Al final tendremos una Single Page Application de Vue totalmente responsiva que va a consumir un servidor con PHP para la gestión de archivos.

Cada usuario tiene acceso solo a sus propios archivos, pero puede compartirlos para el público. Por cierto, los archivos se guardan en el sistema de archivos o disco duro, no en la base de datos (eso sería una ofensa).

El sistema también cuenta con un módulo para iniciar sesión así como la gestión de usuarios en donde se pueden crear, eliminar o cambiarles la contraseña.

Base de datos

Se puede usar MariaDB o MySQL como motor de base de datos. Sin importar cuál elijas, recuerda crear la base de datos que alojará los datos e importar las tablas:

Tenemos tres tablas. Una es de usuarios, otra es de archivos y la tercera es de los archivos que están compartidos. Además, tenemos un usuario administrador por defecto para poder acceder al sistema la primera vez.

La tabla de usuarios guarda los datos de los usuarios, que son el correo y la contraseña hasheada. También tiene una columna para saber si el usuario es administrador. Un administrador puede crear más usuarios.

La tabla de archivos guarda el nombre original, que es el nombre con el que el usuario sube el archivo, así como el nombre real que es un nombre único y aleatorio. También guarda la fecha de creación, el tamaño en bytes y el usuario al que le pertenece.

Finalmente la de los archivos compartidos permite saber si un archivo está compartido a través del id del mismo y un hash aleatorio seguro. De este modo podemos compartir archivos para que cualquier persona los descargue.

Login

Iniciar sesión en sistema de alojamiento de archivos con PHP
Iniciar sesión en sistema de alojamiento de archivos con PHP

Para el login simplemente se solicita el correo y la contraseña del usuario que ya debe estar registrado. Si el correo no existe o la contraseña es inválida, se le indica al usuario. El formulario está validado.

Se requiere que se inicie sesión para que los archivos que se suban a este gestor estén relacionados de cierto modo al usuario.

Gestor de archivos en la nube con PHP

Comencemos viendo la parte para subir archivos. Los archivos se pueden seleccionar o arrastrar y soltar.

Subiendo archivos al sistema de drive en PHP
Subiendo archivos al sistema de drive en PHP

El sistema permite la subida de cualquier tipo de archivo, en cualquier cantidad. No hay límite en el peso más que por restricciones de PHP y el php.ini.

Todos los archivos subidos aparecen en Mis archivos que es lo que vendría a ser el Disco en la nube o espacio de almacenamiento del usuario:

Archivos en la nube con software escrito en PHP
Archivos en la nube con software escrito en PHP

Como puedes ver tenemos la lista de archivos del usuario. De nuevo te digo, los verdaderos archivos “físicos” están en el disco duro, aquí solo están sus detalles. El usuario puede descargar el archivo, eliminarlo o compartirlo.

Quiero que notes los iconos de los archivos, este icono depende de su extensión y no aparece por arte de magia. Está debidamente programado. Tenemos la columna con un icono:

El icono se obtiene con la función obtenerIcono que está así:

Mismo que solo es un puente para la siguiente función:

Primero extraigo la extensión cortando la parte que está después del punto, luego la uso como clave para acceder al diccionario de iconos. Si la clave no existe, entonces se regresa el icono por defecto. Ah, estoy usando los iconos de Material Design.

Si quieres agregar más iconos simplemente agrega más entradas al diccionario, yo agregué las que creí necesarias.

Compartiendo archivo

Compartir archivo a través de enlace - Sistema de alojamiento de archivos con PHP
Compartir archivo a través de enlace – Sistema de alojamiento de archivos con PHP

Se puede compartir un archivo con el público en general, es decir, cualquier usuario con acceso al link. Simplemente se verifica si el usuario es dueño del archivo y en caso de que sí, se genera un hash aleatorio seguro.

Este enlace puede ser compartido y cualquier persona puede descargar el archivo.  En cualquier momento se puede dejar de compartir y el link ya no será válido.

Archivo todavía no compartido
Archivo todavía no compartido

Por cierto, el diálogo que aparece para compartir el archivo es un ejemplo de cómo pasar propiedades a un componente en Vue.

Descarga de archivos

Se me hace importante resaltar este aspecto. Podríamos servir el archivo con Apache y evitarnos optimizaciones, pero debido a la gestión de permisos debemos hacerlo con PHP.

Anteriormente en mi blog ya te mostré que se puede forzar la descarga de un archivo con readfile, pero para archivos grandes es mejor hacerlo por fragmentos. Y en este caso el código que descarga un archivo público es:

La magia ocurre en la función servirArchivoParaDescargar:

Con esto podemos servir archivos de cualquier tamaño, o bueno, yo he probado descargando archivos de hasta 3.2 GB.

Protección de los archivos

A nivel de sistema operativo, los archivos están en el mismo directorio y no tienen ninguna protección (sería interesante encriptarlos). La protección se añade en primer lugar con Apache, denegando el acceso a esa carpeta.

En segundo lugar, PHP se encarga de servir el archivo solo si le pertenece al usuario.

Contenido del directorio en donde se guardan los archivos
Contenido del directorio en donde se guardan los archivos

Todos los archivos se guardan con un id aleatorio, además de que se les remueve la extensión pues al final ésta no importa (ya que el nombre original se encuentra en la base de datos).

Gestión de usuarios

Ya para terminar la explicación de este sistema que permite tener una nube en una red local o en internet usando PHP y MySQL te mostraré la parte de los usuarios:

Gestión de usuarios para nube con PHP y Vue
Gestión de usuarios para nube con PHP y Vue

Lo que se puede hacer es cambiar la contraseña, darle permisos de administrador o eliminarlo. En este caso para cambiar la contraseña se solicita la contraseña actual y la nueva:

Cambiando contraseña de usuario
Cambiando contraseña de usuario

Instalación del sistema

Necesitas contar con composer y con npm, así como con una pila LAMP.

Descarga el código fuente y colócalo en tu carpeta pública del servidor Apache. Normalmente es C:\xampp\htdocs en Windows.

Una vez que lo tengas entra a api y ejecuta composer install para instalar todas las dependencias de PHP. Luego sal de ella, entra a frontend y ejecuta npm install para instalar las dependencias del lado del cliente.

En la carpeta api crea un archivo llamado env.php tomando como ejemplo el archivo env.ejemplo.php y configura las credenciales de la base de datos. No olvides importar las tablas junto con la creación del primer usuario.

También es importante configurar el archivo .env y .env.production dentro de frontend para que coincidan con la ruta en donde has montado el proyecto.

Dentro de frontend ejecuta npm run serve y visita localhost:8080 para visitar el servidor de desarrollo.

Otros puntos importantes son:

Configurar el directorio en donde estarán todos los archivos. Por defecto es en la carpeta subidas en el directorio de la api. Este directorio debe ser creado si no existe.

Proteger ese directorio con Apache o el servidor que se esté usando, así no se permiten las descargas sin autorización. Lo siguiente puede ser el ejemplo del .htaccess:

Recuerda ajustar las variables post_max_size, upload_max_filesize, memory_limit y max_file_uploads en el archivo php.ini según tus necesidades.

La variable memory_limit debería ser mayor que post_max_size y upload_max_filesize, aunque en el caso de las descargas he probado con archivos de hasta 3.2 GB y no hay problemas, teniendo 128M como valor en memory_limit.

Preparando para producción

Este sistema se puede montar en cualquier lugar que tenga Apache, PHP y MySQL. No es necesario contar con NPM ni nada de eso, pues éste último solo sirve para el desarrollo del lado del cliente.

Para llevar a producción hay que compilar todos los archivos y generar los css, js y html. Aquí las instrucciones:

Ejecutar npm run build y copiar al servidor de producción solo la carpeta api y todos los archivos generados dentro de frontend/dist.

Lee bien: debes copiar todos los archivos generados de manera que estos sean hermanos de la carpeta api, y no solo copiar la carpeta llamada dist. Solo como referencia, el directorio de producción en mi caso es gestor_archivos_php_prod y se ve así:

Una vez que hayas copiado api, edita el archivo cors.php y establece la variable $produccion en true.

Conclusión

Este proyecto fue una mejora muy grande a un simple script para subir archivos con PHP. De hecho el código que se encarga de procesar los archivos es muy parecido.

Puedes montar este proyecto en un servidor de casa o en un hosting para tener tu propio disco en la nube. Yo lo he montado en una computadora un tanto antigua que corre sobre Linux. Y como lo dije, el sistema es totalmente responsivo:

Gestor de archivos en la nube con PHP - Captura en dispositivo móvil
Gestor de archivos en la nube con PHP – Captura en dispositivo móvil

El código fuente de este sistema es open source y gratuito para descargar, justo como mis otros proyectos. No puedo explicar cada apartado y línea, pues sería un post muy extenso. Por lo tanto dejaré el código completo en mi GitHub.

Te dejo otros enlaces para ver más sobre PHP y JavaScript.

Encantado de ayudarte


Estoy disponible para trabajar en tu proyecto, modificar el programa del post o realizar tu tarea pendiente, no dudes en ponerte en contacto conmigo.

No te pierdas ninguno de mis posts

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

16 comentarios en “Software gestor de archivos en la nube con PHP y MySQL”

  1. Al pasarlo a producción y en un servidor de ferozo solo puedo agregar un usuario y un archivo, al querer agregar un segundo archivo o usuario me salta el siguiente error, “Error subiendo archivo/usuario, unexpected end of json input” ¿Cual puede ser el error? Aclaro que el directorio se encuentra con los permisos adecuados en el servidor. Muchas gracias!

  2. DIsculpe quiero implementar algo asi en mi negocio tengo una base de datos pequeña de mis clientes con facturas…pero quiero que cada cliente tenga un usurario y entre a descargar su facturas en pdf seria un proceso similar?

Dejar un comentario