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)

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

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