• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • DirectoryIterator::__construct()

    (PHP 5,PHP 7)

    Constructs a new directory iterator from a path

    说明

    publicDirectoryIterator::__construct(string $path)

    Constructs a new directory iterator from a path.

    参数

    $path

    The path of the directory to traverse.

    错误/异常

    Throws anUnexpectedValueExceptionif the$pathcannot be opened.

    Throws aRuntimeExceptionif the$pathis an empty string.

    更新日志

    版本说明
    5.3.0ThrowsUnexpectedValueExceptionif the$pathcannot be opened.
    5.1.3ThrowsRuntimeExceptionif the$pathis an empty string.
    5.1.0ThrowsRuntimeExceptionon error.Previously,threwException.

    范例

    Example#1 ADirectoryIterator::__construct()example

    This example will list the contents of the directory containing the script.

    <?php
    $dir = new DirectoryIterator(dirname(__FILE__));
    foreach ($dir as $fileinfo) {
        if (!$fileinfo->isDot()) {
            var_dump($fileinfo->getFilename());
        }
    }
    ?>
    

    参见

    • SplFileInfo
    • Iterator
    Here's all-in-one DirectoryIterator:
    <?php
    /**
     * Real Recursive Directory Iterator
     */
    class RRDI extends RecursiveIteratorIterator {
     /**
      * Creates Real Recursive Directory Iterator
      * @param string $path
      * @param int $flags
      * @return DirectoryIterator
      */
     public function __construct($path, $flags = 0) {
      parent::__construct(new RecursiveDirectoryIterator($path, $flags));
     }
    }
    /**
     * Real RecursiveDirectoryIterator Filtered Class
     * Returns only those items which filenames match given regex
     */
    class AdvancedDirectoryIterator extends FilterIterator {
     /**
      * Regex storage
      * @var string
      */
     private $regex;
     /**
      * Creates new AdvancedDirectoryIterator
      * @param string $path, prefix with '-R ' for recursive, postfix with /[wildcards] for matching
      * @param int $flags
      * @return DirectoryIterator
      */
     public function __construct($path, $flags = 0) {
      if (strpos($path, '-R ') === 0) { $recursive = true; $path = substr($path, 3); }
      if (preg_match('~/?([^/]*\*[^/]*)$~', $path, $matches)) { // matched wildcards in filename
       $path = substr($path, 0, -strlen($matches[1]) - 1); // strip wildcards part from path
       $this->regex = '~^' . str_replace('*', '.*', str_replace('.', '\.', $matches[1])) . '$~'; // convert wildcards to regex 
       if (!$path) $path = '.'; // if no path given, we assume CWD
      }
      parent::__construct($recursive ? new RRDI($path, $flags) : new DirectoryIterator($path));
     }
     /**
      * Checks for regex in current filename, or matches all if no regex specified
      * @return bool
      */
     public function accept() { // FilterIterator method
      return $this->regex === null ? true : preg_match($this->regex, $this->getInnerIterator() >getFilename());
     }
    }
    ?>
    Some examples:
    <?php
    /* @var $i DirectoryIterator */
    foreach (new AdvancedDirectoryIterator('.') as $i) echo $i->getPathname() . '<br/>';
    // will output all files and directories in CWD
    foreach (new AdvancedDirectoryIterator('-R *.php') as $i) echo $i->getPathname() . '<br/>';
    // will output all php files in CWD and all subdirectories
    foreach (new AdvancedDirectoryIterator('-R js/jquery-*.js') as $i) echo $i->getPathname() . '<br/>';
    // will output all jQuery versions in directory js, or throw an exception if directory js doesn't exist
    ?>
    Pretty cool, huh? :)
    Don't store DirectoryIterator objects for later; you will get an error saying "too many open files" when you store more than the operating system limit (usually 256 or 1024).
    For example, this will yield an error if the directory has too many files:
    <?php
    $files = array();
    foreach (new DirectoryIterator('myDir') as $file) {
     $files[] = $file;
    }
    ?>
    Presumably, this approach is memory intensive as well.
    I needed to match in directory tree file name(s) by regular expression. Code is based on Marcus Börger class DirectoryTreeIterator http://cvs.php.net/viewvc.cgi/php-src/ext/spl/examples/ and on examples given in his lecture Introduction to object oriented PHP at PHP Quebec conference 2007 http://talks.somabo.de/
    <?php
    class KeyFilter extends FilterIterator
    {
     private $_rx;
     
     function __construct(Iterator $it, $regex)
     {
      parent::__construct($it);
      $this->_rx= $regex;
     }
     function accept()
     {
      return ereg($this->_rx,$this->getInnerIterator() >key());
     }
     protected function __clone() {
      return false;
     }
    }
    class DirMach extends KeyFilter
    {
     function __construct($path , $regex)
     {
      parent::__construct(
      new DirectoryTreeIterator($path), $regex);
     }
     function current()
     {
      return parent::key();
     }
     function key()
     {
      return parent::key();
     }
    }
    class DirectoryTreeIterator extends RecursiveIteratorIterator
    {
      /** Construct from a path.
       * @param $path directory to iterate
       */
      function __construct($path)
      {
       try {
       parent::__construct(
          new RecursiveCachingIterator(
            new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
            ), 
            CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
          ), 
          parent::SELF_FIRST
        );
       } catch(Exception $e) {
        echo $e->getMessage();
        exit;
       }
      }
      /** @return the current element prefixed with ASCII graphics
       */  
      function current()
      {
       if ($this->hasChildren())
        $this->next(); 
       return $this->key();
      }
      /** Aggregates the inner iterator
       */  
      function __call($func, $params)
      {
       return call_user_func_array(array($this->getSubIterator(), $func), $params);
      }
    }
    $PathToSearch = 'path_to_search';
    $regex = 'regular_expression';
    $FileList = new DirMach($PathToSearch, $regex);
    foreach ($FileList as $file) {
     $match[] = $file;
    }
    echo '<pre>';
    var_dump($match);
    echo '</pre>';
    ?>
    
    Beware that DirectoryIterator returns a reference to itself with each iteration instead of a unique new SplFileInfo object as one may first assume.
    This is important to know if you want to push the results of an iteration into an array for later processing.
    If you do that, then all entries in the array will be the same DirectoryIterator object with the same internal state (most likely invalid - see the valid() method), which is probably not what you want.
    So if you do want to store the iteration results in an array, then you must convert them to either plain strings or new SplFileInfo objects first.
    $todo = [];
    foreach (new DirectoryIterator('/some/dir') as $entry) {
      if (!$entry->isFile()) {
        continue;
      }
      #$todo []= $entry; # Don't do this!
      $todo []= new SplFileInfo($entry->getFilename());  # Do this!
      #$todo []= $entry->getFilename();  # or do this if you're only interested in the file name.
    }
    I need to traverse recursively through a directory tree and get all sub-directory paths and has written a snippet to do that.
    <?php
    $path = "D:\webroot\phpvietnamcms";
    foreach (new RecursiveIteratorIterator(
          new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME), RecursiveIteratorIterator::CHILD_FIRST) as $file => $info) {
      if ($info->isDir()) 
      {
        echo $file."<br />";
      } 
    }
    ?>
    
    udvig dot ericson at gmail dot com
    29-Jul-2006 07:48
    In response to the comment below from udvig. The Example ist wrong, here is the right one:
    <?php
    $dir = new DirectoryIterator("/tmp");
    foreach ($dir as $file) {
      if ($file->isDot()) {
        continue;
      }
      echo $file->getFilename() . "\n";
    }
    ?>
    
    We can now replace the old fashioned way of listing the content from a directory!
    the old way:
    <?php
    if ($handle = opendir('/home/fernando/temp')) {
      while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
          print "$file <br />";
        }
      }
      closedir($handle);
    }
    ?> 
    the new way:
    <?php
    $dir = new DirectoryIterator('/home/fernando/temp');
    while($dir->valid()) {
      if(!$dir->isDot()) {
        print $dir->current()."<br />";
      }
      $dir->next();
    }
    ?>