Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Directory Functions : dir

dir

Return an instance of the Directory class (PHP 4, PHP 5)

Directory {
  Directory(string directory);
  string path ;
  resource handle ;
  string read();
  void rewind();
  void close();
}

A pseudo-object oriented mechanism for reading a directory. The given directory is opened. Two properties are available once the directory has been opened. The handle property can be used with other directory functions such as readdir(), rewinddir() and closedir(). The path property is set to path the directory that was opened. Three methods are available: read, rewind and close.

Examples

Example 504. dir() example

Please note the fashion in which dir::read()'s return value is checked in the example below. We are explicitly testing whether the return value is identical to (equal to and of the same type as - see Comparison Operators for more information) FALSE since otherwise, any directory entry whose name evaluates to FALSE will stop the loop.

<?php
$d
= dir("/etc/php5");
echo
"Handle: " . $d->handle . "\n";
echo
"Path: " . $d->path . "\n";
while (
false !== ($entry = $d->read())) {
  echo
$entry."\n";
}
$d->close();
?>

The above example will output something similar to:

Handle: Resource id #2
Path: /etc/php5
.
..
apache
cgi
cli


Notes

Note:

The order in which directory entries are returned by the read method is system-dependent.

Related Examples ( Source code ) » class.dir










Code Examples / Notes » class.dir

thomas

With SPL, you could recursively list all of the folders inside the current directory like this:
<?php
$it = new RecursiveDirectoryIterator('./');
// RecursiveIteratorIterator accepts the following modes:
//     LEAVES_ONLY = 0  (default)
//     SELF_FIRST  = 1
//     CHILD_FIRST = 2
foreach (new RecursiveIteratorIterator($it, 2) as $path) {
   if ($path->isDir()) {
       echo "$path\n";
   }
}
?>


fordiman

This one's pretty nice.  After getting frustrated for hunting down .jpg files in my massive music collection (PHP would run out of memory), I thought there should be a preg_ls function.
function preg_ls ($path=".", $rec=false, $pat="/.*/") {
// it's going to be used repeatedly, ensure we compile it for speed.
$pat=preg_replace("|(/.*/[^S]*)|s", "\\1S", $pat);
//Remove trailing slashes from path
while (substr($path,-1,1)=="/") $path=substr($path,0,-1);
//also, make sure that $path is a directory and repair any screwups
if (!is_dir($path)) $path=dirname($path);
//assert either truth or falsehoold of $rec, allow no scalars to mean truth
if ($rec!==true) $rec=false;
//get a directory handle
$d=dir($path);
//initialise the output array
$ret=Array();
//loop, reading until there's no more to read
while (false!==($e=$d->read())) {
//Ignore parent- and self-links
if (($e==".")||($e=="..")) continue;
//If we're working recursively and it's a directory, grab and merge
if ($rec && is_dir($path."/".$e)) {
$ret=array_merge($ret,preg_ls($path."/".$e,$rec,$pat));
continue;
}
//If it don't match, exclude it
if (!preg_match($pat,$e)) continue;
//In all other cases, add it to the output array
$ret[]=$path."/".$e;
}
//finally, return the array
return $ret;
}
Not bad for a mere 18 lines, don't you think?
Example use:
foreach (preg_ls("/etc/X11", true, "/.*\.conf/i") as $file) echo $file."\n";
Output:
/etc/X11/xkb/README.config
/etc/X11/xorg.conf-vesa
/etc/X11/xorg.conf~
/etc/X11/gui.conf
/etc/X11/xorg.conf
/etc/X11/xorg.conf-fbdev


cf

The dir Class, from what I can tell, on a Windows box is not a  live image of the directory.  When the class is instantiated it takes a snapshot of the directory and then the iterator works off that.
I may be wrong, but when I run two processes that look to see if a directory exists, and then deletes the dir when some processing takes place.  Deletes from one process do not effect the iteration of the second.
To get around this I check that the file exists before doing my processing:
$d = dir($dataDir);
while (false !== ($entry = $d->read()))
if ($entry != '..' && $entry != '.' && file_exists("$dataDir\\$entry"))
{
   // do stuff
}
$d->close();
I run this as a batch process and can activate it multiple times to process the directory listing in parallel.
-CF


fordiman

Saw the leaf dirs bit...  quick mod:
function preg_ls ($path=".", $rec=false, $pat="/.*/") {
$pat=preg_replace ("|(/.*/[^S]*)|s", "\\1S", $pat);
while (substr ($path,-1,1) =="/") $path=substr ($path,0,-1);
if (!is_dir ($path) ) $path=dirname ($path);
if ($rec!==true) $rec=false;
$d=dir ($path);
$ret=Array ();
while (false!== ($e=$d->read () ) ) {
if ( ($e==".") || ($e=="..") ) continue;
if ($rec && is_dir ($path."/".$e) ) {
$ret=array_merge ($ret,preg_ls($path."/".$e,$rec,$pat));
continue;
}
if (!preg_match ($pat,$e) ) continue;
$ret[]=$path."/".$e;
}
return (empty ($ret) && preg_match ($pat,basename($path))) ? Array ($path."/") : $ret;
}
example:
foreach (preg_ls ("/usr/share/fluxbox", true, "/[LT]e[sa]/i") as $file) echo $file."\n";
output:
/usr/share/fluxbox/styles/Leaf/
/usr/share/fluxbox/styles/Clean
/usr/share/fluxbox/styles/Testing/


22-feb-2006 09:02

Regarding samuel's comment about the dir() function not supporting Unicode properly, it's all in the encoding. The function does NOT internally change Unicode characters into question marks (?), as I was first led to believe. If you simply try to output them in UTF-8, they'll show up just right.

radar

Regarding jaqb's post about a correction to the read_dir function, I have one small fix too if people wish to also list the directories inside this directory and read them into the same array.
<?
function read_dir($dir) {
  $array = array();
  $d = dir($dir);
  while (false !== ($entry = $d->read())) {
      if($entry!='.' && $entry!='..') {
          $entry = $dir.'/'.$entry;
          if(is_dir($entry)) {
  $array[] = $entry;
              $array = array_merge($array, read_dir($entry));
          } else {
              $array[] = $entry;
          }
      }
  }
  $d->close();
  return $array;
}
?>


samuel dot l

Note that the dir object will use the default encoding for non-unicode programs on Windows with PHP 5.x.
So, if you have a file named with characters unsupported by the current default encoding, the dir->read() method will return a wrong entry.
<?php
/*
** This script is on the same directory than a file named with
** unsupported characters for the current default encoding.
*/
$d = dir("./");
while(false !== ($e = $d->read()))
   echo $e . '<br/>';
?>
This will print a "?" for every unsupported characters, and not the right file name. So take care if you check with is_file/is_dir right after enumerating.


alex

IMHO, thats take most effect with smaller number of errors;)

    function get_leaf_dirs($dir)
     {
        $array = array();
        $d = @dir($dir);
        if($d)
        {
              while (false !== ($entry = $d->read()))
              {
                  if($entry!='.' && $entry!='..')
                  {
                      $entry = $dir.'/'.$entry;
                      if(is_dir($entry))
                      {
                          $subdirs = get_leaf_dirs($entry);
                          if ($subdirs)
                            $array = array_merge($array, $subdirs);
                          else
                            $array[] = $entry;
                      }
                  }
              }
              $d->close();
        }
        return $array;
     }


anton backer

i've modified the script below to get the leaf folders of any directory (folders with no subfolders).
note: this does not return the folder passed in as a parameter, even if it has no subfolders.
<?php
function get_leaf_dirs($dir) {
  $array = array();
  $d = dir($dir);
  while (false !== ($entry = $d->read())) {
      if($entry!='.' && $entry!='..') {
          $entry = $dir.'/'.$entry;
          if(is_dir($entry)) {
              $subdirs = get_leaf_dirs($entry);
              if ($subdirs)
                 $array = array_merge($array, $subdirs);
              else
                 $array[] = $entry;
          }
      }
  }
  $d->close();
  return $array;
}
?>


done_to_death

function directoryList($start,$win32=false){
   if($win32){
       $slash="\\";
   }else{
       $slash="/";
   }
   $basename = pathinfo($start);
   $basename = $basename['basename'];
   $ls=array();
   $dir = dir($start);
   while($item = $dir->read()){
       if(is_dir($start.$slash.$item)&& $item!="." && $item!=".."){
           $ls[$basename][]=directoryList($start.$slash.$item,$win32);
       }else{
           if($item!="."&&$item!=".."){
               $ls[$basename][]=$item;
           }
       }
   }
   return $ls;
}
$path = pathinfo(__FILE__);
$ls = directoryList($path['dirname'], true);


http://www.rooftopsolutions.nl

<?php

 $i = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('.'));
?>
works for me..


Change Language


Follow Navioo On Twitter
chdir
chroot
dir
closedir
getcwd
opendir
readdir
rewinddir
scandir
eXTReMe Tracker