PHP tiene cuatro herramientas principales para trabajar con directorios: scandir() para listar el contenido, glob() para buscar con patrones, mkdir() para crear directorios de forma recursiva y RecursiveDirectoryIterator para recorrer árboles completos de ficheros.
scandir(): listar el contenido de un directorio
<?php
// Lista todos los entries, incluyendo '.' y '..'
$todo = scandir('/var/www/app/uploads');
// Filtrar '.' y '..'
$ficheros = array_diff(scandir('/var/www/app/uploads'), ['.', '..']);
// Orden descendente (segundo parámetro)
$descendente = scandir('/var/www/app/uploads', SCANDIR_SORT_DESCENDING);
// Uso habitual: listar solo ficheros (no subdirectorios)
$dir = '/var/www/app/uploads';
$soloFicheros = array_filter(
array_diff(scandir($dir), ['.', '..']),
fn($entry) => is_file("$dir/$entry")
);
?>
glob(): listar ficheros con patrones
glob() acepta los mismos comodines que la shell: * para cualquier cadena, ? para un solo carácter, [abc] para un conjunto y {a,b} para alternativas:
<?php
// Todos los PHP del directorio actual
$phps = glob('*.php');
// Todos los JPG y PNG de uploads
$imagenes = glob('/var/www/app/uploads/*.{jpg,jpeg,png,gif,webp}', GLOB_BRACE);
// Todos los logs de julio de 2026
$logs = glob('/var/log/app/2026-07-*.log');
// Todos los directorios dentro de un path
$subdirs = glob('/var/www/app/*', GLOB_ONLYDIR);
foreach ($imagenes as $ruta) {
echo basename($ruta) . ' - ' . filesize($ruta) . " bytesn";
}
?>
mkdir(): crear directorios
<?php
// Crear un directorio simple
mkdir('/tmp/nuevo-dir');
// Crear con permisos específicos
mkdir('/var/www/app/cache', 0755);
// Crear toda la estructura recursivamente (tercer parámetro true)
$ruta = '/var/www/app/uploads/2026/07/26';
if (!is_dir($ruta)) {
mkdir($ruta, 0755, true); // crea 2026/, 2026/07/, 2026/07/26/
}
?>
Organizar subidas por fecha
<?php
function subirFichero(array $fichero): string
{
$base = '/var/www/app/uploads';
$subdir = date('Y/m/d'); // ej. 2026/07/26
$directorio = "$base/$subdir";
if (!is_dir($directorio)) {
mkdir($directorio, 0755, true);
}
$nombre = uniqid('img_', true) . '.' . pathinfo($fichero['name'], PATHINFO_EXTENSION);
$destino = "$directorio/$nombre";
if (!move_uploaded_file($fichero['tmp_name'], $destino)) {
throw new RuntimeException("No se pudo mover el fichero a $destino");
}
// Ruta relativa para guardar en BD
return "uploads/$subdir/$nombre";
}
?>
RecursiveDirectoryIterator: recorrer árboles
Para recorrer un directorio con todos sus subdirectorios, RecursiveDirectoryIterator combinado con RecursiveIteratorIterator es la herramienta más potente:
<?php
$directorio = '/var/www/app/src';
$iterador = new RecursiveDirectoryIterator(
$directorio,
RecursiveDirectoryIterator::SKIP_DOTS
);
$aplanado = new RecursiveIteratorIterator($iterador);
foreach ($aplanado as $fichero) {
if ($fichero->isFile()) {
echo $fichero->getRealPath() . "n";
}
}
?>
Buscar ficheros por extensión en todo el árbol
<?php
function buscarPorExtension(string $directorio, string $extension): array
{
$resultado = [];
$iterador = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($directorio, FilesystemIterator::SKIP_DOTS)
);
foreach ($iterador as $fichero) {
if (strtolower($fichero->getExtension()) === strtolower($extension)) {
$resultado[] = $fichero->getRealPath();
}
}
return $resultado;
}
// Buscar todos los ficheros .log en /var/log
$logs = buscarPorExtension('/var/log', 'log');
echo count($logs) . " ficheros .log encontradosn";
// Buscar todos los .php en el proyecto
$phps = buscarPorExtension('/var/www/app/src', 'php');
echo count($phps) . " ficheros PHP encontradosn";
?>
Calcular el tamaño de un directorio
<?php
function tamanoDirectorio(string $directorio): int
{
$total = 0;
$iterador = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($directorio, FilesystemIterator::SKIP_DOTS)
);
foreach ($iterador as $fichero) {
$total += $fichero->getSize();
}
return $total;
}
$bytes = tamanoDirectorio('/var/www/app/uploads');
echo number_format($bytes / 1024 / 1024, 2) . ' MB';
?>
La documentación de RecursiveDirectoryIterator cubre las opciones de FilesystemIterator y los flags para controlar qué incluir en la iteración.
