Here's a RecursiveDirectoryIterator class I've written and find quite useful:
<?php /** * This class encapsulates an iterator that iterates over all the files in a * directory recursively. Only files that don't begin with a '.' are included * in this iteration. This class essentially wraps an SPL DirectoryIterator * object and returns each file in the iteration as an SplFileInfo. * * @author <a href="mailto:phi...@lightbox.org">Philip Graham</a> */ class Util_RecursiveFileIterator implements Iterator { CONST SHOW_DOT_FILES = true; private $_basePath; private $_curDirIter; private $_dirStack; private $_showDots; /** * Constructor. By default the iteration will skip any files that begin * with a '.' character but this can be changed by passing the class * constant SHOW_DOT_FILES as the second parameter. * * @param string $basePath - The base path of the directory to iterate over * @param boolean $showDots - Whether or not to include files that begin * with a '.' character in the iteration. */ public function __construct($basePath, $showDots = false) { // PREPARE ... THE ... HUMANOID if(!is_dir($basePath)) { $basePath = dirname($basePath); } if(!$basePath) { $basePath = '.'; } // If the given path is relative this function will transform it // into an equivalent path. This call assumes that the relative path // is relative to the file that created this iterator. $this->_basePath = Util_File::getAbsolutePath($basePath, 2); $this->_showDots = $showDots; } /** * Returns the current value of the iteration * * @return FileInfoInfo */ public function current() { return $this->_curDirIter->current(); } /** * Returns the index of the current entry. * * @return string */ public function key() { $curPath = $this->_curDirIter->getPathname(); $relativeToBase = substr($curPath, strlen($this->_basePath)); return $relativeToBase; } /** * Moves the directory iterator to the next element of the iteration. */ public function next() { $this->_curDirIter->next(); $good = false; while(!$good) { if(!$this->_curDirIter->valid()) { if(count($this->_dirStack) == 0) { $good = true; } else { $this->_curDirIter = array_pop($this->_dirStack); } } else if($this->_curDirIter->isDot()) { if(!$this->_showDots) { $this->_curDirIter->next(); } else { $good = true; } } else if(!$this->_showDots && substr($this->_curDirIter->getFileName(), 0, 1) == '.') { $this->_curDirIter->next(); } else if($this->_curDirIter->isDir()) { // Create a new iterator for the sub-dir $newIter = new DirectoryIterator( $this->_curDirIter->getPathname()); // Make sure the current iterator is ready to go when it // gets popped off the stack $this->_curDirIter->next(); // Push it... push it real good array_push($this->_dirStack, $this->_curDirIter); // Set the new iterator $this->_curDirIter = $newIter; } else { $good = true; } } } /** * Resets the iterator to first file in the object's base path. */ public function rewind() { $this->_curDirIter = new DirectoryIterator($this->_basePath); $this->_dirStack = array(); if(!$this->_showDots && $this->_curDirIter->isDot()) { $this->next(); } } /** * Returns a boolean indicating wether or not there are anymore elements left * in the iteration. */ public function valid() { return $this->_curDirIter->valid(); } } Usage: $dirIter = new Util_RecursiveFileIterator('/path/to/directory'); foreach($dirIter AS $fileName => $fileInfo) { // $fileName is the basename of the file and $fileInfo is a SplFileInfo // for the file } Hope this helps! On February 23, 2009 11:31:04 Ryan Panning wrote: > I have discovered that when I foreach over a RecursiveDirectoryIterator > (see example below) the $item actually turns into a SplFileInfo object. > I would expect it to be a RecursiveDirectoryIterator. How do I do a > hasChildren() on SplFileInfo? > > However, if I change it to a non-recursive, DirectoryIterator, $item is > what I would expect, DirectoryIterator. I've tested this with 5.2.8 and > 5.3b1. I'm guessing this is an issue with my setup as I'm sure I've > gotten this to work before... > > > $dir = new RecursiveDirectoryIterator('/path/to/dir'); > foreach ($dir as $item) { > print get_class($item) . "\r\n"; > } -- Philip Graham Lightbox Technologies Suite 312 240 Catherine St. Ottawa, ON, K2P 2G8 613-686-1661 ext. 102 -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php