Espera un momento ...
¿Te gustaría llevar mi curso de Laravel, gratis?
Sólo debes ingresar tus datos:
La gestión de archivos en proyectos backend es una necesidad súper común.
¿Alguna vez has tenido dificultad para almacenar y/o compartir archivos en tus proyectos Laravel?
Ahora verás que en realidad es muy sencillo.
¿En qué casos trabajamos con archivos?
Laravel abstrae todo lo concerniente a almacenamiento de archivos en su integración llamada File Storage.
E incluye drivers para trabajar con archivos de manera local, pero también en la nube, por ejemplo con Amazon S3.
Mejor aún, es muy sencillo cambiar entre estas opciones.
De tal manera que nuestro servidor de producción y de desarrollo podrán usar diferentes configuraciones, pero el código será el mismo para ambos.
Para esto sólo necesitamos ir al archivo de configuración ubicado en config/filesystems.php
.
Dentro de este archivo podemos configurar los llamados "disks".
Cada "disk" declarado se asocia con un driver y determina dónde se van a almacenar nuestros archivos.
local
interactúa con los archivos almacenados en nuestro propio proyecto Laravel.s3
usa el servicio S3 de Amazon.Si tu proyecto a penas está empezando y no vas a usar un servicio como S3, lo más recomendable es usar la carpeta storage
.
Es decir, es posible almacenar tus archivos directamente sobre la carpeta public
, pero no es lo ideal.
Al guardar tus archivos dentro de storage, puedes decidir si quieres que sean públicos o privados.
Esta clase fachada permite guardar archivos fácilmente:
Storage::put('pdf/nombre_archivo.pdf', $contenido);
Para leer archivos, puedes usar:
Storage::get('pdf/nombre_archivo.pdf');
Vamos a crear un disco para guardar archivos de forma privada.
Y en este ejemplo, vamos a guardar archivos PDF, que sólo los usuarios con los permisos adecuados podrán ver.
Para esto, en el arreglo disks
(que está en config\filesystems.php
), vamos a agregar el siguiente disco:
'disks' => [
'private_files' => [
'driver' => 'local',
'root' => storage_path('app/private'),
],
// ...
],
// ...
A nuestro disk le hemos puesto el nombre private_files
.
Dentro del mismo archivo de configuración, en la parte superior encontramos el disco por defecto:
'default' => env('FILESYSTEM_DRIVER', 'private_files'),
Como puedes ver, el valor se lee desde la variable FILESYSTEM_DRIVER
.
Sólo debemos ir a nuestro archivo .env
y declarar dicha variable (o actualizar su valor si ya la tenemos).
FILESYSTEM_DRIVER="private_files"
De tal manera que en nuestro controlador, cuando un usuario suba un archivo, tendremos lo siguiente:
if ($request->file('pdf')) {
$uploadedFile = $request->file('pdf');
$shortName = Str::random(6) . '.pdf';
$filePath = '/pdf/' . $shortName;
Storage::put($filePath, file_get_contents($uploadedFile));
}
$filePath
determina dónde se va a guardar nuestro archivo y con qué nombre.file_get_contents
obtiene el contenido del archivo subido.Si quieres que Laravel genere el nombre del archivo por ti, también es posible.
En ese caso usarías: $assignedPath = Storage::put($folderPath, $uploadedFile);
Puedes guardar en tu base de datos el path hacia el archivo, o si la carpeta destino es estándar, sólo el nombre del archivo.
Luego, puedes definir una ruta para que tus usuarios accedan a sus archivos.
Y tu controlador se vería más o menos de esta forma:
class FileController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function show($shortName)
{
$pdf = DocumentFile::where('short_name', $shortName)->firstOrFail();
$hasAccess = UserPermission::where('user_id', auth()->id())->where('folder_id', $pdf->folder_id)->exists();
if ($hasAccess) {
return Storage::download('pdf/' . $shortName);
}
return back();
}
// ...
}
Sobre este ejemplo:
auth
asegura que sólo usuarios que han iniciado sesión puedan acceder a los PDF.DocumentFile
representa cada PDF subido al sistema.UserPermission
determina el permiso que tienen los usuarios respecto a las carpetas.Lo importante es que, si el usuario tiene los permisos suficientes, puedes generar la descarga del archivo usando:
return Storage::download($filePath);
Es decir, debes indicar la carpeta y el nombre del archivo, de la misma manera que usamos put
para determinar dónde subir.
Comparte este post si te fue de ayuda 🙂.
Regístrate
Accede a todos los cursos, y resuelve todas tus dudas.
Cursos Recomendados
Aprende Laravel desde cero y desarrolla aplicaciones web reales, en tiempo récord, de la mano de Laravel.
Iniciar cursoActualiza tus proyectos desde cualquier versión hasta la última versión estable de Laravel.
Iniciar cursoDesarrollemos un Messenger! Aprende sobre Channels, Queues, Vuex, JWT, Sesiones, BootstrapVue y mucho más.
Iniciar cursoEspera un momento ...
¿Te gustaría llevar mi curso de Laravel, gratis?
Sólo debes ingresar tus datos: