venerdì 14 dicembre 2007

PHP: Ricerca File in Directory

Rispondo ad una domanda ricevuta da un lettore (stile rubrica Donna Letizia)

Sto cercando di scrivere una funzione in PHP per la ricerca di un file con una certa estensione partendo da una directory e includendo nella ricerca tutte le sotto-directory contenute in essa anche su più livelli. Fino ad elencare tutti i file di una directory ci arrivo, ma il problema è che non so in anticipo quanti livelli di sotto-directory ci sono e come fare ad includerli tutti nella ricerca. Sembrava facile, ma mi sono bloccato. Se potessi darmi un suggerimento, forse una funzione di ricerca file può servire anche ad altri.

Per fare una cosa di questo genere conviene usare una funzione ricorsiva. Si passano come argomenti il percorso della cartella da cui iniziare la ricerca, l'estensione cercata e un array che conterrà i file trovati. Con l'istruzione readdir si elencano tutti i file e le directory, con preg_match si trovano i file con l'estensione desiderata e si aggiungono all'array, mentre la funzione richiama sè stessa ricorsivamente su ogni directory incontrata.

Il codice è

function searchFile($folder, $srch, &$results) {
  $folder = rtrim($folder, "/") . '/';
  if ($hd = opendir($folder)) {
    while (false !== ($file = readdir($hd))) { 
      if($file != '.' && $file != '..') {
        if(is_dir($folder . $file)) {
          searchFile($folder. $file, $srch, $results);
        } elseif(preg_match("#\.$srch$#", $file)) {
          $results[] = $folder . $file;
        }
      }
    }
    closedir($hd); 
  }
}

Un esempio di utilizzo potrebbe essere il seguente

$r=array();
searchFile('c:/test/', 'exe', $r);
foreach($r as $f) {
  echo $f, '<br />';
}

Si cercano tutti i file con estensione exe nella directory c:/test e tutte le sue sotto-directory e si stampa poi l'array dei risultati.

Da notare che il percorso della cartella da cui iniziare la ricerca va indicato utilizzando il separatore di directory stile Unix ( / ) e non Windows ( \ ).

Se poi si volesse modificare la funzione per effettuare una ricerca in base al nome esatto e non all'estensione del file, basterebbe passare il nome del file nell'argomento $srch e modificare questa unica riga

} elseif(preg_match("#\.$srch$#", $file)) {
in questo modo
} elseif($srch == $file) {

Tutto qui. Spero possa essere utile.

Le funzioni ricorsive sono una soluzione ideale per attraversare strutture ad albero in cui la profondità dei livelli (nel nostro esempio directory e sotto-directory) non sia predeterminabile.

Può essere difficile capire il meccanismo le prime volte che si incontrano funzioni di questo tipo, ma per chi fosse interessato ad approfondire la cosa i motori di ricerca offrono tutto il materiale che si vuole anche con esempi di codice diversi da quello che abbiamo visto.

Nessun commento:

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.