dir()
Scopri come lavorare con le directory in PHP: aprirle, leggerle, crearle ed eliminarle con le funzioni integrate.
Introduzione
Questo capitolo illustra come lavorare con le directory in PHP: aprirle, leggerle, crearle ed eliminarle, oltre alla funzione dir() ormai rimossa e alle sue sostituzioni moderne. PHP include un insieme completo di funzioni integrate per questi compiti, quindi puoi elencare il contenuto di una cartella, scorrere un albero di directory o ripulire i file senza ricorrere al sistema operativo.
Le funzioni per le directory sono più utili quando si costruisce un gestore di upload, si genera un elenco di file per una pagina di download, si puliscono i file temporanei o si analizza una cartella di template o immagini in fase di esecuzione.
Comprendere le funzioni per le directory in PHP
PHP raggruppa le operazioni sulle directory in un insieme di funzioni procedurali, oltre a una classe orientata agli oggetti chiamata DirectoryIterator. Le più comuni sono:
opendir()— apre una directory e restituisce un handle (una risorsa da cui leggere)readdir()— legge la voce successiva da un handle di directory apertoclosedir()— chiude un handle di directory e libera la risorsascandir()— legge tutte le voci in un array con una sola chiamataglob()— restituisce i percorsi che corrispondono a un pattern con caratteri jolly della shellmkdir()— crea una nuova directoryrmdir()— elimina una directory vuotais_dir()— verifica se un percorso è una directory
Ogni elenco di directory in PHP include le voci speciali . (la directory stessa) e .. (la directory padre). Quasi sempre è necessario saltare queste voci — dimenticarselo è una fonte comune di bug.
Usare opendir() e readdir() per leggere una directory
opendir() apre una directory e restituisce un handle di directory. Si passa poi quell'handle a readdir(), che restituisce il nome della voce successiva a ogni chiamata, e false quando non ci sono più voci. Chiudi sempre l'handle con closedir() quando hai finito.
Poiché readdir() può restituire legittimamente "0" (un file letteralmente chiamato 0), confronta il risultato con !== false anziché un confronto lasco, per evitare che un nome file falsy venga scambiato per la fine dell'elenco.
Esempio di opendir() e readdir() in PHP
<?php
$dir = "/path/to/directory";
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if ($file === "." || $file === "..") {
continue; // skip self and parent
}
echo "filename: " . $file . PHP_EOL;
}
closedir($dh);
}
}Per una directory contenente a.txt, b.log e report.csv, questo stampa:
filename: b.log
filename: report.csv
filename: a.txtL'ordine non è alfabetico — readdir() restituisce le voci nell'ordine in cui il filesystem le memorizza. Se hai bisogno di un ordine prevedibile, usa scandir() (che ordina) oppure ordina tu stesso i risultati.
Usare scandir() per elencare una directory in un colpo solo
scandir() legge l'intero contenuto di una directory in un array con una singola chiamata e — a differenza di readdir() — ordina il risultato alfabeticamente per impostazione predefinita. Questo è il modo più comodo per ottenere un elenco ordinato di file. Include comunque . e .., quindi filtrali quando vuoi solo i file reali.
Utilizzo della funzione scandir() in PHP
<?php
$dir = "/path/to/directory";
$files = scandir($dir);
print_r($files);Per una directory contenente a.txt, b.log e report.csv, l'output è:
Array
(
[0] => .
[1] => ..
[2] => a.txt
[3] => b.log
[4] => report.csv
)Passa SCANDIR_SORT_DESCENDING come terzo argomento per invertire l'ordine, o SCANDIR_SORT_NONE per saltare l'ordinamento (più veloce per directory molto grandi).
Trovare file con glob()
Quando vuoi solo i file che corrispondono a un pattern — tutti i file .txt, o tutto ciò che inizia con report — glob() è l'opzione più pulita. Accetta un pattern con caratteri jolly della shell e restituisce un array di percorsi corrispondenti:
<?php
foreach (glob("/path/to/directory/*.txt") as $file) {
echo $file . PHP_EOL;
}Se solo a.txt corrisponde nella nostra directory di esempio, questo stampa:
/path/to/directory/a.txtA differenza di scandir(), glob() non include . e .., e restituisce percorsi completi anziché semplici nomi di file.
Creare directory con mkdir()
La funzione mkdir() crea una nuova directory. Il primo argomento è il percorso, il secondo imposta i permessi (un valore ottale come 0755), e il terzo argomento opzionale, se true, crea ricorsivamente le directory padre mancanti.
Utilizzo della funzione mkdir() in PHP
mkdir("/path/to/my/new/directory", 0755, true);Senza il flag true, mkdir() fallisce con un avviso se una directory padre non esiste già. Nei sistemi Unix-like i permessi effettivi sono influenzati anche dalla umask del processo.
Eliminare directory con rmdir()
La funzione rmdir() elimina una directory. Accetta il percorso della directory che vuoi rimuovere.
Utilizzo della funzione rmdir() in PHP
rmdir("/path/to/my/new/directory");Nota: rmdir() rimuove solo directory vuote. Per eliminare una directory che contiene ancora file, rimuovi prima i file (e le eventuali sottodirectory) — ad esempio iterando il contenuto con scandir() e chiamando unlink() su ogni file.
Il sostituto moderno: DirectoryIterator
Per il codice orientato agli oggetti, la classe SPL DirectoryIterator è il modo consigliato per scorrere una directory. È iterabile con foreach e fornisce informazioni dettagliate su ogni voce — nome, dimensione, tipo e data di modifica — senza chiamate a funzioni separate:
<?php
foreach (new DirectoryIterator("/path/to/directory") as $entry) {
if ($entry->isDot()) {
continue; // skip "." and ".."
}
echo $entry->getFilename() . PHP_EOL;
}Per una directory contenente a.txt, b.log e report.csv, questo stampa:
b.log
report.csv
a.txtisDot() salta comodamente sia . che .. con un unico controllo. Per scorrere un intero albero di directory, incluse le sottocartelle, usa RecursiveDirectoryIterator insieme a RecursiveIteratorIterator.
La funzione legacy dir()
Deprecata: La funzione
dir()è stata deprecata in PHP 7.4 e rimossa in PHP 8.0. UsaDirectoryIteratoroscandir()al suo posto. L'esempio seguente è fornito solo per la manutenzione di codice più vecchio.
La funzione dir() restituisce un object Directory che offre un modo orientato agli oggetti per leggere il contenuto di una directory. A differenza di scandir(), che restituisce un semplice array, dir() restituisce un object con metodi come read(), rewind() e close(). Nota che dir() non è un alias di scandir() — hanno scopi diversi e restituiscono tipi di dati diversi.
Utilizzo della funzione dir() in PHP (legacy)
<?php
$dir = dir("/path/to/directory");
while (($file = $dir->read()) !== false) {
echo "filename: " . $file . PHP_EOL;
}
$dir->close();Conclusione
PHP offre diversi modi per lavorare con le directory. Usa scandir() o glob() per elenchi rapidi e ordinati, il trio opendir()/readdir()/closedir() quando vuoi leggere le voci una alla volta, e DirectoryIterator per un'iterazione pulita orientata agli oggetti. Crea e rimuovi cartelle con mkdir() e rmdir(), e ricorri a RecursiveDirectoryIterator quando hai bisogno di scendere nelle sottodirectory. Per una visione più ampia del lavoro con il filesystem, consulta i capitoli PHP Directory e PHP Filesystem.