Hay un par de maneras diferentes de ir sobre algo como esto, voy a dar dos enfoques rápidos para que usted pueda elegir: rápido y sucio, frente larga y menos sucio (aunque, es un viernes por la noche por lo que' re permitido ir un poco loco).
1. Rápida (y sucio)
Esto implica sólo escribir una expresión regular (podría ser dividida en múltiples) para filtrar la colección de archivos de un solo golpe rápido.
(solo las dos líneas de comentarios son muy importantes para el concepto.)
$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;
}
Este enfoque tiene una serie de problemas, a pesar de que es rápido de implementar ser sólo una sola línea (aunque el regex puede ser un dolor para descifrar).
2. Menos rápida (y menos sucio)
Un reutilizable enfoque más es crear un par de filtros a medida (usando expresiones regulares, o lo que quiera!) Para reducir gradualmente la lista de los disponibles artículos en la inicial RecursiveDirectoryIterator
hasta solo aquellos que desee. El siguiente es solo un ejemplo, escrito rápidamente solo para usted, de extender el RecursiveRegexIterator
.
Comenzamos con una clase base cuyo trabajo principal es retener la expresión regular con la que queremos filtrar, todo lo demás se difiere de nuevo al RecursiveRegexIterator
. Tenga en cuenta que la clase es abstract
ya que en realidad no es do nada útil: el filtrado real lo deben hacer las dos clases, que ampliarán este. Además, se puede llamar FilesystemRegexFilter
, pero no hay nada que obligue (en este nivel) a filtrar las clases relacionadas con el sistema de archivos (hubiera elegido un nombre mejor, si no tuviera tanto sueño).
abstract class FilesystemRegexFilter extends RecursiveRegexIterator {
protected $regex;
public function __construct(RecursiveIterator $it, $regex) {
$this->regex = $regex;
parent::__construct($it, $regex);
}
}
Estas dos clases son filtros muy básicos, que actúan sobre el nombre del archivo y el nombre del directorio, respectivamente.
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()));
}
}
para poner esos en práctica, los siguiente se repite recursivamente a través de los contenidos del directorio en el que reside el guión (no dude en modificar este!) Y filtra los .Trash
carpetas (asegurándose de que los nombres de las carpetas hacer coincidir la expresión regular especialmente diseñada), y aceptar solo archivos PHP y 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;
}
De particular interés es que, dado que nuestros filtros son recursivos, podemos optar por jugar con la forma de iterar sobre ellos. Por ejemplo, podríamos fácilmente nos limitamos a analizar únicamente hasta 2 niveles de profundidad (incluyendo la carpeta de partida) haciendo:
$files = new RecursiveIteratorIterator($filter);
$files->setMaxDepth(1); // Two levels, the parameter is zero-based.
foreach($files as $file) {
echo $file . PHP_EOL;
}
También es súper fácil de añadir aún más filtros (creando una instancia de más de nuestro filtrado clases con diferentes expresiones regulares, o creando nuevas clases de filtrado) para necesidades de filtrado más especializadas (por ejemplo, tamaño de archivo, longitud de ruta completa, etc.).
P.S. Hmm esta respuesta balbucea un poco; Traté de mantenerlo lo más conciso posible (incluso eliminando vastas franjas de super-balbuceo). Disculpas si el resultado neto deja la respuesta incoherente.
Realmente aprecio el enfoque Menos rápido (y menos sucio) que demuestra exactamente lo que estoy buscando. Gracias. Aunque la rápida y sucia hicieron error con Fatal error: no detectada excepción 'UnexpectedValueException' con el mensaje 'RecursiveDirectoryIterator :: __ construct (/var/www/html/.Trash-0) – Chris
El error es nada realmente mal con el código (bar no 'try' -ing lo suficientemente fuerte), la causa más probable son los permisos de la carpeta (o la falta de ella). Me alegra que estés contento con la mejor alternativa de todos modos. :) – salathe
Muy bien, pero ¿cómo se obtiene un objeto SplFileInfo para cada archivo, en lugar de una ruta simple? –