regex - How to use RegexIterator in PHP -
i have yet find example of how use php regexiterator recursively traverse directory.
the end result want specify directory , find files in given extensions. example html/php extensions. furthermore, want filter out folders such of type .trash-0, .trash-500 etc.
<?php $directory = new recursivedirectoryiterator("/var/www/dev/"); $it = new recursiveiteratoriterator($directory); $regex = new regexiterator($it,'/^.+\.php$/i',recursiveregexiterator::get_match); foreach($regex $v){ echo $value."<br/>"; } ?>
is have far result in : fatal error: uncaught exception 'unexpectedvalueexception' message 'recursivedirectoryiterator::__construct(/media/hdmovies1/.trash-0)
any suggestions?
there couple of different ways of going this, i'll give 2 quick approaches choose from: quick , dirty, versus longer , less dirty (though, it's friday night we're allowed go little bit crazy).
1. quick (and dirty)
this involves writing regular expression (could split multiple) use filter collection of files in 1 quick swoop.
(only 2 commented lines important concept.)
$directory = new recursivedirectoryiterator(__dir__); $flattened = new recursiveiteratoriterator($directory); // make sure path not contain "/.trash*" folders , ends eith .php or .html file $files = new regexiterator($flattened, '#^(?:[a-z]:)?(?:/(?!\.trash)[^/]+)+/[^/]+\.(?:php|html)$#di'); foreach($files $file) { echo $file . php_eol; }
this approach has number of issues, though quick implement being one-liner (though regex might pain decipher).
2. less quick (and less dirty)
a more re-usable approach create couple of bespoke filters (using regex, or whatever like!) whittle down list of available items in initial recursivedirectoryiterator
down want. following 1 example, written you, of extending recursiveregexiterator
.
we start base class main job keep hold of regex want filter with, else deferred recursiveregexiterator
. note class abstract
since doesn't do useful: actual filtering done 2 classes extend one. also, may called filesystemregexfilter
there nothing forcing (at level) filter filesystem-related classes (i'd have chosen better name, if weren't quite sleepy).
abstract class filesystemregexfilter extends recursiveregexiterator { protected $regex; public function __construct(recursiveiterator $it, $regex) { $this->regex = $regex; parent::__construct($it, $regex); } }
these 2 classes basic filters, acting on file name , directory name respectively.
class filenamefilter extends filesystemregexfilter { // filter files against regex public function accept() { return ( ! $this->isfile() || preg_match($this->regex, $this->getfilename())); } } class dirnamefilter extends filesystemregexfilter { // filter directories against regex public function accept() { return ( ! $this->isdir() || preg_match($this->regex, $this->getfilename())); } }
to put practice, following iterates recursively on contents of directory in script resides (feel free edit this!) , filters out .trash
folders (by making sure folder names do match specially crafted regex), , accepting php , html files.
$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) $file) { echo $file . php_eol; }
of particular note since our filters recursive, can choose play around how iterate on them. example, limit ourselves scanning 2 levels deep (including starting folder) doing:
$files = new recursiveiteratoriterator($filter); $files->setmaxdepth(1); // 2 levels, parameter zero-based. foreach($files $file) { echo $file . php_eol; }
it super-easy add yet more filters (by instantiating more of our filtering classes different regexes; or, creating new filtering classes) more specialised filtering needs (e.g. file size, full-path length, etc.).
p.s. hmm answer babbles bit; tried keep concise possible (even removing vast swathes of super-babble). apologies if net result leaves answer incoherent.
Comments
Post a Comment