Lista archivos de un directorio en PHP

<?php
 
// Path where diplomas are stored.
$initial_path = '/var/www/diplomas';
 
// Courses and levels structure. Should match with your current filesystem.
$diplomas = [
'chinese' => [
'introduction',
],
'japanese' => [
'basic-1',
'basic-2',
],
];
 
foreach ($diplomas as $course => $levels) {
foreach ($levels as $level) {
$folder = $initial_path . '/' . $course . '/' . $level;
if (!is_dir($folder)) {
continue;
}
 
$scanned = array_diff(scandir($folder), ['..', '.']);
 
if (empty($scanned)) {
continue;
}
echo PHP_EOL . $course . '/' . $level . PHP_EOL . PHP_EOL; // Optional printing.
foreach ($scanned as $file) {
// The next code is optional. Do whatever you want with $file variable.
$link = 'diplomas/' . $course . '/' . $level . '/' . $file;
$name = trim( str_replace( '.pdf', '', $file ) );
$html = '<a href="' . $link . '" class="d-block btn-link" target="_blank">' . $name . '</a>';
echo $html . PHP_EOL; // Optional printing.
}
}
}

Contexto

Tengo una escuela de idiomas como cliente y necesita subir diplomas, mensualmente, de sus alumnos inscritos.

Los diplomas me lo envían en formato PDF dentro de sus respectivas carpetas. La estructura es la siguiente:

diplomas/
├─ chinese/
│ ├─ introduction/
│ │ ├─ student-name-1.pdf
├─ japanese/
│ ├─ basic-1/
│ │ ├─ student-name-1.pdf
│ │ ├─ student-name-2.pdf
│ ├─ basic-2/
│ │ ├─ student-name-1.pdf
│ │ ├─ student-name-2.pdf

Tenemos la carpeta raíz diplomas, y dentro de el existen carpetas con los niveles escolares y al final encontramos los diplomas en formato PDF.

El requerimiento es poner los diplomas en el servidor para que los usuarios accedan a su diploma apretando un enlace. Hacer esto manualmente es complicado cuando tienes más de 50 diplomas.

Así que pensé, mejor escribo un script en PHP para que haga todo automáticamente, y ya solo insertaría los directorios donde quiero leer los diplomas.

Demo

En el siguiente demo imprimo los diplomas en sus respectivos enlaces utilizando el código anterior.

Explicación

Las variables $initial_path y $diplomas son variables que cambiarás acorde a tu proyecto.

En el demo anterior, almaceno los diplomas en la siguiente ruta:

/var/www/diplomas

Si tu tienes tus archivos dentro de la ruta /var/www/my-site.com/public_html/diplomas/, entonces la variable $initial_path debería ser definida así:

$initial_path = '/var/www/my-site.com/public_html/diplomas/';

La variable $diplomas la puedes renombrar de acuerdo a tu proyecto, tal vez tu manejes $facturas o simplemente $archivos.

Sea como sea, tiene que ser un array y su contenido tiene que seguir la estructura actual de tus directorios y archivos, tal como lo hice en el demo.

Después de tener listo las variables $initial_path y $diplomas, ahora el script empezará a leer la variable $diplomas con un foreach, así obtendremos los datos necesarios para seguir leyendo las carpetas que hay dentro.

<?php
 
// Path where diplomas are stored.
$initial_path = '/var/www/diplomas';
 
// Courses and levels structure. Should match with your current filesystem.
$diplomas = [
'chinese' => [
'introduction',
],
'japanese' => [
'basic-1',
'basic-2',
],
];
 
foreach ($diplomas as $course => $levels) {
foreach ($levels as $level) {
$folder = $initial_path . '/' . $course . '/' . $level;
if (!is_dir($folder)) {
continue;
}
 
$scanned = array_diff(scandir($folder), ['..', '.']);
 
if (empty($scanned)) {
continue;
}
echo PHP_EOL . $course . '/' . $level . PHP_EOL . PHP_EOL; // Optional printing.
foreach ($scanned as $file) { ...
// The next code is optional. Do whatever you want with $file variable.
$link = 'diplomas/' . $course . '/' . $level . '/' . $file;
$name = trim( str_replace( '.pdf', '', $file ) );
$html = '<a href="' . $link . '" class="d-block btn-link" target="_blank">' . $name . '</a>';
echo $html . PHP_EOL; // Optional printing.
}
}
}

Si te fijas bien, uso dos foreach al principio, el primero es para leer los cursos como chinese y japanese, y el segundo es para leer las carpetas que hay dentro de cada curso.

Ahora hay que construir el $folder donde vamos a listar los archivos .txt. Hay que aplicarle la función is_dir() para determinar si $folder es un directorio.

Después para leer los archivos .txt dentro de $folder, hay que usar la función scandir(). Esta función va a enumerar los archivos y directorios de la ruta que especifiquemos.

Por default, la función scandir() va retornar . y .., los cuales son directorios específicos en Linux.

Si no los necesitas, entonces aplica la siguiente función para quitarlos del resultado final:

$scanned = array_diff(scandir($folder), ['..', '.']);

El resultado de la función anterior debemos aplicarle una validación si el array resultando es vacío. Si es vacío, entonces no continúa el loop.

Si hay archivos dentro de la variable $scanned, entonces puedes aplicar otro foreach para leer los archivos y dentro de ese loop podrás hacer lo que quieras con ese archivos.

En mi caso, lo que hago es generar enlaces para que los usuarios puedan hacerle click y abrir su diploma en una nueva pestaña. Esta parte dependerá de tus requerimientos al momento de usar la lista de archivos generada.

0

Escrito por Roel Magdaleno

Desarrollador Backend y Performance Engineer.

Deja un comentario

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