Directory Helper: Tool per la scansione delle directory. (v1.0)

13 Apr 2019 | M.A.D.R.

Quante volte abbiamo avuto bisogno di avere la lista dei nostri file in modo ricorsivo all'interno delle directory? Oggi parliamo di Directory Helper, snippet indispensabile per tutti...

Sappiamo bene che un qualsiasi progetto dinamico e non necessita del controllo delle directory e soprattutto il controllo dei file al loro interno.

Directory Helper è uno snippet capace di informare l'utente in tempo reale su tutte le directory semplicemente attraverso semplici funzioni.

Per i più curiosi non parliamo di "scandir" ma di "DirectoryIterator" tool indispensabile per effettuare la scansione in modo ottimale delle nostre directory.

Notiamo sin da subito che la necessità di gestire un grande quantitativo di dati/file è legata soprattutto alla tipologia del progetto, infatti basti immaginare un portale dove ogni utente ha facoltà di caricare delle immagini.

In questo scenario seppur semplificato, la necessità di un programmatore è quella di ottimizzare le risorse, e quindi di conseguenza effettuare una scansione man mano delle immagini utili all'app e quello che oramai sono da considerarsi inutili...

Immaginiamo ora che il nostro script di upload immagini crei un token per ogni utente in base all'username e alla data, diventa così quasi impossibile arrivare a profondità elevate senza dover ricorrere a escamotage più o meno belli.

La soluzione più immediata sarebbe creare un'indice di tutti i file che si aggiorni ogni 2 ore, o magari durante la notte...

Lo snippet Directory Helper effettua ricorsivamente la lettura delle directory e restituisce in modo chiaro ed univoco il risultato dell'alberatura delle dir sottoposte a scansione...

Vediamo brevemente un piccolo estratto:

function array_to_dir($dir,$associative=true){
	$data=[];
	if(is_array($dir)){
		foreach ($dir as $k=>$v){
		    $data=array_merge($data,scandir_($v));
		}
	}else{
		$data=scandir_($dir);
	}
	if($associative){
		$local=$data;
		$data=[];
		foreach ($local as $k=>$v){
			$t=explode('/',$v);
			$ext=end(explode(".", $v));
			$data[str_replace($ext,'',array_pop($t))]=$v;
		}
	}
	return $data;
}

Come possiamo vedere questa prima parte è stata scritta in modo da far comprendere a tutti il funzionamento, non è ottimizzata ma funziona egregiamente.

Vediamo un richiamo ad un'altra funzione "scandir_" che altro non è il wrapper di "scandir" che non ha assolutamente necessità di essere commentata.

Questo snipper così formattato ha già tutto l'occorrente per essere utilizzato nel nostro progetto.

Allora perchè utilizzare DirectoryIterator?

Semplice, è più performante e la scrittura risulta essere più breve.

Sapevi che l'esecuzione di uno script cambia in base alla dimensione del file?

Ebbene si, più sarà grande il file che andremo a richiamare più sarà grande il tempo d'attesa per l'esecuzione...

Vediamo come utilizzare la recursion_performance.

Partiamo con definire i 3 parametri chiave:

  • directory: directory di partenza
  • assoc: ossia array associativo (valore booleano, utile per ricorsione su più directory)
  • red_dir: valore booleano per effettuare la scansione ricorsiva.

Per utilizzarlo e testare il reale comportamento dello snippet basta richiamarlo in questo modo:

print_r(recursion_performance(__DIR__.'',true,true));

Cosa abbiamo fatto?

Abbiamo detto di leggere ricorsivamente tutte le directory ed il loro contenuto partendo dalla locazione del nostro file che la richiama.

Infatti possiamo vedere come sia assoc che rec_dir siano impostate su true.

Infine vi lascio alla lettura della seconda release di Directory Helper!

Buona lettura.

/**
 * Copyright (c) 2019. Licenza Open Source - public domine
 * Il codice di questo file è reso disponibile secondo le regole vigente e con licenza d'uso PD.
 * Il codice riportato è un programma di cui codice sorgente è reso disponibile completo di tutte le sue
 * funzionalità e può essere modificato secondo le proprie esigenze.
 * Qualora il codice risultasse copiato su altri portali senza citarne la fonte saranno applicate tutte le
 * disposizioni in materia di Proprietà Intellettuale.
 */

/**
 * Created by phpS
 * User: macus_adi
 * Project Name: utils_git
 * File: dir_helper.php
 * Path: root/helper/dir_helper.php
 * Date: 13/04/2019
 * Time: 12:42
 */


function scandir_($dir=''){
	$data=[];
	foreach (scandir($dir) as $k=>$v){
		if($v!='.' && $v!='..' && !is_dir($dir.'/'.$v))$data[]=$dir.'/'.$v;
	}
	return $data;
}

function array_to_dir($dir,$associative=true){
	$data=[];
	if(is_array($dir)){
		foreach ($dir as $k=>$v){
		    $data=array_merge($data,scandir_($v));
		}
	}else{
		$data=scandir_($dir);
	}
	if($associative){
		$local=$data;
		$data=[];
		foreach ($local as $k=>$v){
			$t=explode('/',$v);
			$ext=end(explode(".", $v));
			$data[str_replace($ext,'',array_pop($t))]=$v;
		}
	}
	return $data;
}

function recursion_performance($dir,$assoc=false,$rec_dir=false){
	$data = [];
	$recursion = new DirectoryIterator($dir);
	foreach($recursion as $fileinfo) {
		if($fileinfo->isDot()) continue;
		if($assoc){
			if(!$fileinfo->isDir())$data[$fileinfo->getFilename()] =$dir.'/'.$fileinfo->getFilename();
			elseif($rec_dir)$data[$fileinfo->getFilename()]=recursion_performance($dir.'/'.$fileinfo->getFilename(),$assoc,$rec_dir);
		}else{
			if(!$fileinfo->isDir())$data[] =$fileinfo->getFilename();
			elseif($rec_dir)$data[]=recursion_performance($dir.'/'.$fileinfo->getFilename(),$assoc,$rec_dir);
		}
	}
	return $data;
}

Soluzioni complete per ogni esigenza