Fonction glob récursive
Par CrazyCat le 27/05/2010, 10:45 - PHP - Lien permanent
La fonction glob est utilisée dans de nombreux langages, elle sert à lister tous les fichiers (et répertoires) qui vérifient un masque.
La petite fonction qui suit sert à rechercher tous les fichiers qui vérifient un masque dans une arborescence.
<?php /** * Recursive glob * @param string $pattern Masque à vérifier * @param string $path Répertoire initial * @param integer $flags Drapeaux * @return array list of files */ function rglob($pattern='*', $path='', $flags = 0) { $paths=glob($path.'*', GLOB_MARK|GLOB_ONLYDIR|GLOB_NOSORT); $files=glob($path.$pattern, $flags); foreach ($paths as $path) { $files=array_merge($files,rglob($pattern, $path, $flags)); } return $files; } ?>
Les drapeaux sont ceux utilisés par la fonction glob:
- GLOB_MARK : Ajoute un slash final à chaque dossier retourné
- GLOB_NOSORT : Retourne les fichiers tant l'ordre d'apparence (pas de tri)
- GLOB_NOCHECK : Retourne le masque de recherche si aucun fichier n'a été trouvé
- GLOB_NOESCAPE : Ne protège aucun métacaractère d'un antislash
- GLOB_BRACE : Remplace {a,b,c} par 'a', 'b' ou 'c'
- GLOB_ONLYDIR : Ne retourne que les dossiers qui vérifient le masque
- GLOB_ERR : Stop lors d'une erreur (comme des dossiers non lisibles), par défaut, les erreurs sont ignorées.
Commentaires
Ou encore en PERL
!/usr/bin/perl -w use File::Glob ':glob'; sub rglob { my $path = shift || '.'; my $pattern = shift || '*'; my $flags = shift || 0; my @elements = bsd_glob ( sprintf( '%s/%s' => ($path, $pattern)) , $flags ); my @folder = grep { -d && $_ } @elements; my @files = grep { -D && $_ } @elements; foreach (@folder) { next if /^\.\.?/; push @files => ( rglob( $_, $pattern, $flags ) ); } return @files; }Merci Fabien, voila qui sera fort utile à de nombreuses personnes :)
Ce bout de code peut etre optimisé:
my @folder = grep { -d && $_ } @elements; my @files = grep { -D && $_ } @elements;avec
my (@files, @folder); map { (-d $_) ? (push @folder => $_) : (push @files => $_) } @elements;Juste un détail: il est connu que les fonctions récursives sont plus lentes que les fonctions itératives (changement de contexte sur la pile, etc...). Il est possible d'écrire la fonction rglob en itératif: