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 '<br>' . $course . '/' . $level . '<br><br>'; // 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 . '<br>'; // 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 abres el demo en una ventana nueva y te vas al File Explorer, encontrarás los directorios y archivos manejados en el demo.

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.

foreach ($diplomas as $course => $levels) {
  foreach ($levels as $level) {
     ...
  }
}

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.

Roel Magdaleno
Escrito por Roel Magdaleno

Roel Magdaleno es un ingeniero informático especializado en desarrollo web desde hace más de 5 años. Desarrolla sitios web, aplicaciones web, plugins para WordPress y scripts con PHP y JavaScript. Además, comparte su conocimiento en su blog personal.

Deja un comentario