Il y a plusieurs façons de faire quelque chose comme ça, je vais vous donner deux approches rapides: rapide et sale, plutôt longue et moins sale (bien que ce soit un vendredi soir donc nous ' re autorisé à aller un peu fou).
1. rapide (et sale)
Cela implique simplement écrire une expression régulière (peut être divisé en plusieurs) pour filtrer la collection de fichiers d'un seul coup rapide.
(Seules les deux lignes commentées sont vraiment importantes pour le concept.)
$directory = new RecursiveDirectoryIterator(__DIR__);
$flattened = new RecursiveIteratorIterator($directory);
// Make sure the path does not contain "/.Trash*" folders and ends eith a .php or .html file
$files = new RegexIterator($flattened, '#^(?:[A-Z]:)?(?:/(?!\.Trash)[^/]+)+/[^/]+\.(?:php|html)$#Di');
foreach($files as $file) {
echo $file . PHP_EOL;
}
Cette approche a un certain nombre de questions, mais il est rapide à mettre en œuvre étant juste une ligne unique (bien que la regex pourrait être une peine à déchiffrer).
2. Moins rapide (et moins sale)
Une approche plus réutilisable est de créer un couple de filtres sur mesure (utilisant l'expression rationnelle, ou tout ce que vous voulez!) Pour rogner la liste des disponibles éléments dans le RecursiveDirectoryIterator
initial à seulement ceux que vous voulez. Ce qui suit est seulement un exemple, écrit rapidement juste pour vous, d'étendre le RecursiveRegexIterator
.
Nous commençons par une classe de base dont le travail principal est de conserver l'expression rationnelle avec laquelle nous voulons filtrer, tout le reste est reporté au RecursiveRegexIterator
. Notez que la classe est abstract
car elle ne fait pas quoi que ce soit d'utile: le filtrage proprement dit doit être fait par les deux classes qui vont l'étendre. En outre, il peut être appelé FilesystemRegexFilter
mais rien ne l'oblige (à ce niveau) à filtrer les classes liées au système de fichiers (j'aurais choisi un meilleur nom, si je n'étais pas si endormi).
abstract class FilesystemRegexFilter extends RecursiveRegexIterator {
protected $regex;
public function __construct(RecursiveIterator $it, $regex) {
$this->regex = $regex;
parent::__construct($it, $regex);
}
}
Ces deux classes sont des filtres très basiques, agissant respectivement sur le nom du fichier et du répertoire.
class FilenameFilter extends FilesystemRegexFilter {
// Filter files against the regex
public function accept() {
return (! $this->isFile() || preg_match($this->regex, $this->getFilename()));
}
}
class DirnameFilter extends FilesystemRegexFilter {
// Filter directories against the regex
public function accept() {
return (! $this->isDir() || preg_match($this->regex, $this->getFilename()));
}
}
Pour mettre ceux en pratique, les itère suivantes récursive sur le contenu du répertoire dans lequel le script réside (ne hésitez pas à modifier cela!) Et filtre les .Trash
dossiers (en vous assurant que les noms de dossier faire correspondre la regex spécialement conçu), et en acceptant seulement les fichiers PHP et HTML.
$directory = new RecursiveDirectoryIterator(__DIR__);
// Filter out ".Trash*" folders
$filter = new DirnameFilter($directory, '/^(?!\.Trash)/');
// Filter PHP/HTML files
$filter = new FilenameFilter($filter, '/\.(?:php|html)$/');
foreach(new RecursiveIteratorIterator($filter) as $file) {
echo $file . PHP_EOL;
}
À noter en particulier que, puisque nos filtres sont récursives, nous pouvons choisir de jouer avec la façon de itérer sur eux. Par exemple, nous en faisant pourrait facilement nous limiter à seulement numériser jusqu'à profonds 2 niveaux (y compris le dossier de départ):
$files = new RecursiveIteratorIterator($filter);
$files->setMaxDepth(1); // Two levels, the parameter is zero-based.
foreach($files as $file) {
echo $file . PHP_EOL;
}
Il est également très facile d'ajouter des filtres encore plus (par instanciation plus de notre filtrage classes avec des expressions régulières différentes ou, en créant de nouvelles classes de filtrage) pour des besoins de filtrage plus spécialisés (par exemple, taille de fichier, longueur de chemin complet, etc.).
P.S. Hmm cette réponse babille un peu; J'ai essayé de le garder aussi concis que possible (même en enlevant de vastes pans de super-babillage). Toutes mes excuses si le résultat net laisse la réponse incohérente.
Vraiment apprécier l'approche moins rapide (et moins sale), il montre exactement ce que je cherche. Merci. Bien que rapide et sale a fait l'erreur avec Fatal error: Uncaught exception 'UnexpectedValueException' message « RecursiveDirectoryIterator :: __ construct (/var/www/html/.Trash-0) – Chris
L'erreur est vraiment rien de mal avec la code (la barre n'essaye pas assez), la cause la plus probable est les permissions du dossier (ou son absence). Heureux que tu sois heureux avec la meilleure alternative de toute façon. :) – salathe
Très bien, mais comment obtenir un objet SplFileInfo pour chaque fichier, plutôt qu'un simple chemin? –