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.
Indice
Come funziona glob()
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.