back to top

PHP: usare glob() per scansionare il contenuto di una cartella

Un’utilissima (ma non altrettanto conosciuta) funzione del PHP è certamente glob() la quale consente di identificare tutti i file e cartelle che corrispondo ad un determinato pattern. Essa restituisce un array contenente i file e le directory individuati tramite la ricerca eseguita. Per via di tali caratteristiche, glob() potrà essere utilizzata come alternativa ai costrutti basati su opendir() per l’apertura delle cartelle e a readdir() per la lettura dei contenuti presenti all’interno di esse.

Un semplice pattern per i confronti potrebbe essere formato dal carattere jolly "*", che in pratica significa "tutto" o "qualsiasi", e da un’estensione, ad esempio ".png" come nell’esempio proposto di seguito:

foreach (glob("*.png") as $nomefile) {
  echo "Dimensione " . $nomefile . ": " . filesize($nomefile) . "\n";
}

Sostanzialmente tale ciclo permette di stampare il nome di ciascun file ".png" e di indicarne la dimensione tramite la funzione filesize().

Volendo avremmo potuto essere ancora più selettivi e cercare, ad esempio, solo i file il cui nome inizia con "a", modificando il pattern in questo modo:

glob("a*.png")

Un esempio pratico di utilizzo di glob()

La funzione glob() si rivela molto utile nelle operazioni di esplorazione delle cartelle in quanto consente di estrarre unicamente quei file che corrispondono ad un determinato modello di corrispondenza (nell’esempio precedente abbiamo estratto solo il file immagine di tipo PNG). Si supponga, ad esempio, di avere, all’interno della root del nostro sito web, una cartella files contenente una pluralità di file di vario tipo (ad esempio: PDF, DOC e immagini). Si supponga altresì di voler mostrare agli utenti il contenuto di questa cartella filtrandone tuttavia i risultati in base al tipo di file.

Ovviamente potremmo raggiungere questo obiettivo in diversi modi ma, certamente, la via più semplice passa attraverso l’utilizzo della funzione glob() per filtrare le risultanze. Vediamo qualche esempio per chiarire meglio la situazione.

Supponiamo di voler estrarre solo i file PDF dalla cartella files:

$pdf = glob('files/*.pdf');
print_r($pdf);

Quello che abbiamo fatto è di creare una variabile $pdf che andrà a contenere le risultanze ell’operazione eseguita con glob(). In pratica il contenuto della nostra variabile sarà un array con i pathname delle corrispondenze trovate.

Tornando al nostro esempio vediamo come costruire un rudimentale file explorer che mostri solo i file di un certo tipo. Creiamo, quindi, un file esplora.php con questo contenuto

<?php
// recupero dalla querystring il tipo di file da mostrare
$tipo = $_GET['tipo'];

// verifico che il tipo sia supportato
if (!preg_match('/^(pdf|doc|jpg|gif|png)$/', $tipo)) {
  echo 'Tipo non supportato';
  exit;  
}

// estraggo i file con la giusta estensione
$f = glob('files/*.'.$tipo);

// faccio un ciclo e stanpo a video i nomi dei files corrispondenti
foreach ($f as $filename) {
  echo basename($filename) . '<br>';
}
?>

Per testarne il funzionamento si provi a richiamare il file appena creato in questo modo:

http://localhost/esplora.php?tipo=png

L’utilizzo di GLOB_BRACE

Per rendere più preciso l’esito dei confronti sono disponibili alcuni flag, come per esempio GLOB_BRACE che permette di espandere l’espressione {a,b,c} in modo che la ricerca venga effettuata tenendo conto di ciascun elemento che essa contiene.

Il flag presentato potrà essere utilizzato per esempio per proporre più estensioni sulla base delle quali effettuare i confronti, come nello script seguente che estrae un file a caso da una directory purché esso sia un JPEG, un PNG o un’immagine GIF:

function img_casuale($directory) {
  $immagine = glob($directory . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
  shuffle($immagine);
  return basename(array_pop($immagine));
}

Una semplicissima galleria di immagini con glob()

A titolo esemplificativo delle potenzialità di glob() vi presento uno script per creare una semplice galleria d’immagini con PHP. La galleria di immagini viene creata in automatico estraendo tutte le immagini presenti in una data cartella. Lo script è semplicissimo ed ha un design a dir poco rudimentale… lascio quindi a voi il compito di abbellirlo a vostro piacimento e secondo le vostre necessità.

<?php
// imposto glob per estrarre tutti i file da una data cartella
// non ho impostato filtri di alcun tipo, seleziono tutti i file.
$files = glob('images/*.*');

// imposto un array con le estensioni dei file da considerare
// non avendo impostato filtri con glob() questo mi restituirà ogni file nella cartella!
$estensioni_ok = array('gif','jpg','jpeg','png');

// faccio un ciclo del file trovati da glob()
for ($i=0; $i < count($files); $i++) {

  // singolo file
  $image = $files[$i];

  // trovo l'estensione del file
  $ext = strtolower(pathinfo($image, PATHINFO_EXTENSION));

  // mostro solo le immagini con estensione ammessa
  if (in_array($ext, $estensioni_ok)) {
    echo '<div>';
    echo basename($image) . '<br>';
    echo '<img src="' . $image .'" alt="">';
    echo '</div>';
  } else {
    continue;
  }
}
?>

Considerazioni circa l’utilizzo di glob()

Quando si intende utilizzare la funzione glob() è bene tenere presente che essa non opera su file remoti e che i file da analizzare dovranno essere accessibili tramite il filesystem del server corrente; inoltre essa non è utilizzabile su SunOS, mentre GLOB_BRACE non sarà disponibile su alcuni sistemi operativi Unix-based come Solaris OS.

L’utilità di questa funzione consiste sopratutto nella possibilità di esplorare il contenuto di cartelle di cui non si conosce esattamente le dimensioni ed il contenuto potendone filtrare (in modo molto semplice) il contenuto. E’ bene precisare, tuttavia, che l’uso della funzione glob() è piuttosto dispendioso dal punti di vista della RAM. Se la directory da esplorare è molto grande (migliaia di files) potrebbe rivelarsi più performate l’utilizzo di opendir().

glob() Vs. opendir()

Ecco un semplice listato che vi potrebbe essere utile per fare un test di confronto circa le performance delle due funzioni:

<?php
function microtime_float() {
  list ($msec, $sec) = explode(' ', microtime());
  $microtime = (float)$msec + (float)$sec;
  return $microtime;
} 

// verifico il tempo di esecuzione di opendir()
$start_time = microtime_float();
ob_start();
for ($x=0; $x<=20; $x++) {
  $dir = opendir ("foto/");
  while (false !== ($file = readdir($dir))) {
    if (strpos($file, '.jpg', 1)) {
      echo basename($file) . "<br>";
    }
  }
}
ob_end_clean();
echo (microtime_float() - $start_time) . " (opendir time)<br />";

// verifico il tempo di esecuzione di glob()
$start_time = microtime_float();
ob_start();
for ($x=0; $x<=20; $x++) {
  foreach (glob("foto/*.jpg") as $filename) {
    echo basename($filename) . "<br>";
  }
}
ob_end_clean();
echo (microtime_float() - $start_time) . " (glob time)<br />";
?>

Nel mio caso ho effettuato un test con una cartella "foto" in cui vi sono 10 immagini JPEG. Il risultato è stato che opendir() risulta più veloce di glob(). Ecco i miei numeri:

  • opendir(): 0.0015790462493896
  • glob(): 0.001716136932373

La differenza, come potete vedere, è minima ma, in determinati contesti di criticità, nahce le piccole cose possonofare la differenza.

Pubblicitร 
Massimiliano Bossi
Massimiliano Bossi
Stregato dalla rete sin dai tempi delle BBS e dei modem a 2.400 baud, ho avuto la fortuna di poter trasformare la mia passione in un lavoro (nonostante una Laurea in Giurisprudenza). Adoro scrivere codice e mi occupo quotidianamente di comunicazione, design e nuovi media digitali. Orgogliosamente "nerd" sono il fondatore di MRW.it (per il quale ho scritto centinaia di articoli) e di una nota Web-Agency (dove seguo in prima persona progetti digitali per numerosi clienti sia in Italia che all'estero).

Leggi anche...

Correggere l’errore the uploaded file exceeds the upload_max_filesize directive in php.ini

L'errore the uploaded file exceeds the upload_max_filesize directive in...

Cannot modify header information – headers already sent: come risolvere l’errore PHP

L'errore di PHP cannot modify header information - headers...

Ricavare l’estensione di un file con PHP

Quando si lavora con i file in un'applicazione web,...

GD Library: creazione, manipolazione e ridimensionamento immagini con PHP

Le librerie GD (o GD Library), sono componenti fondamentali...

PHP: impostare il fuso orario italiano

Le tue pagine PHP non mostrano l’orario corretto? Probabilmente...
Pubblicitร