PHP: 目录函数库 - Manual
PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links | my php.net 
search for in the  
<dio_writechdir>
view the version of this page
Last updated: Sun, 27 Feb 2005

XXVI. 目录函数库

����

�����ⲿ���ļ�Ϳ��Լ��뱾�չģ���֧�֡�

�װ

��Щ�����Ϊ PHP ���ĵ�һ�֣����豻�װ��ʹ�á�

����ʱ����

���չģ��δ����κ�����ָ�

Ԥ��峣�

������Щ�����ɸ��չģ�鶨��ģ����ֻ���ڸ��չģ�鱻���뵽 PHP �У����������ʱ�̬���غ���Щ������Ч�

DIRECTORY_SEPARATOR (string)

PATH_SEPARATOR (string)

�μ�

相关函数例如 dirname()is_dir()mkdir()rmdir(),见文件系统函数库一节。

目录
chdir -- 改变目录
chroot -- 改变根目录
dir -- directory 类
closedir -- 关闭目录句柄
getcwd -- 取得当前工作目录
opendir -- 打开目录句柄
readdir -- 从目录句柄中读取条目
rewinddir -- 倒回目录句柄
scandir --  列出指定路径中的文件和目录


add a note add a note User Contributed Notes
目录函数库
tatui at indatasolutions dot com dot br
03-Mar-2005 07:37
How to access shared drives in the network:

Is you are using IIS and want to access \\FILESERVER\SHARE_NAME\ and your web server is not a domain controler. You will need to make your webserver runs as a user from the same domain the FILESERVER belongs to.

 As an example:

+ Create a new user called IUSR_<webserver> on the domain controler

+ Make this new user a member of the domain's guest group

+ Go to the Internet Information Services

+ Inside Properties, choose Directory Security

+ on Anonymous access and authentication control... edit

+ change the Account used for anonymous access to the new user created before. In our example: IUSR_<webserver>@<domain name>

After that you will need to take care of local security access. You will need to grant access for this new user on the webserver. Like if you use sessions you need to grant access to this user on the temp directory that your php is using.

enjoy
bardoartifex at yahoo dot com dot br
23-Feb-2005 03:00
Hi, I worked a lot with some usefull recursive functions and one "C pointer-like" approach using PHP. The result is a small code to read directories and files to generate an associative array.

I hope if this will be usefull for you as was to me. (Ah, sorry by my poor english!)

There it's the code:

function &walkThroughDir ($path,&$filelist)
{
     if (!is_dir($path)) return NULL;
    
     $resdir = @opendir ($path) or die("Error reading ".$path);
    
     // It's the secret for this recursive function
     $ret = &$filelist;

     while ( ($entry=readdir($resdir))!==false ) {

           if ( is_dir($path."/".$entry)=="dir" ) { //if it's a directory...
                
                 if ($entry!="." and $entry!="..") {//do not use ./ or ../
                       // Call himself using the same result array
                       walkThroughDir($path."/".$entry,$ret);
                 }//if
           } else {
                 // if it is not a dir, read the filenames
                 $ret[$path][] = $entry;
           }//if

     }//while

     closedir($resdir);
     return $ret;

}//walkThroughDir

This function will generate something alike:
Array
(
   [/Library/WebServer/Documents/component/test/subtest] => Array
       (
           [0] => linuxitscool.php
       )
   [/Library/WebServer/Documents/component/test] => Array
       (
           [0] => macosxrulez.php
           [1] => unixrulez.php
       )
   [/Library/WebServer/Documents/dev/component] => Array
       (
           [0] => Component.h.php
           [1] => Component.pkg.php
       )
)
14-Feb-2005 04:18
selfsimilar at yahoo

what you really should be doing is urlencode()ing rather than manually replacing " " with "%20" and either turning off magic_quotes_gpc or using stripslashes() rather than manually replacing \' with '
selfsimilar at yahoo dot com
13-Jan-2005 08:44
David's script is great, but there are a few problems if you really want to use it. If you're worried about security you probably shouldn't use this anyways, but with David's code, an inquisitive person could manually send a uri that ends in "?moverse=../" and still move up a directory. Also, at least with the version of PHP on my server (unsure of version), any uri with a single quote (') would end up with a backslash preceding it. I think this is more to do with using the GET method instead of POST, but I haven't delved that deep. I also added some '\n' action for html readability and replaced whitespace with percentage codes.

<?php
$path
= "./";

if (
strrpos($moverse,'..')) {
  
$moverse = str_replace('/..','',$moverse);
  
$moverse = substr($moverse,0,strrpos($moverse,'/'));
}

if (
strpos($moverse,'..')===false) { // php is weakly typed
} else if (strpos($moverse,'..')==0) {
   echo
'<span style="font-size: 150%;"><b>Bad Hacker = No caffeine</b></span>';
  
$moverse="";
}

if(
$moverse) {
  
$moverse = $moverse."/";
   if (
strpos($moverse,"\'")) { // This corrects a uri that includes single quote(s), which I think gets messed up by GET
    
$moverse = str_replace("\'","'",$moverse);
   }
}

echo
$moverse."<br/>"."\n";

$handle=opendir($path.$moverse);

while (
$file = readdir($handle)) {
   if(
is_dir($path.$moverse.$file) && $file != ".") {
       if (
$file == ".." && $moverse == "") {
    
       } else {
          
$uri=str_replace(" ","%20",$moverse.$file);
           echo
'<a href="?moverse='.$uri.'">'.$file.'</a><br/>'."\n";
       }
   } else if (
$file != "." && $file != "index.php") {
      
$uri=str_replace(" ","%20",$path.$moverse.$file);
       echo
'<a href="'.$uri.'">'.$file.'</a><br/>'."\n";
   }
}
?>
david
20-May-2004 02:04
a little juiced up version of turgon64�s script.
before the $moverse was getting very long if you where doing a lot of moving around in directorys and also i was unable to open files.
also, now you�re not able to move above the specified path

<?php
$path
= "./";

if (
strrpos($moverse,'..')) {
  
$moverse = str_replace('/..','',$moverse);
  
$moverse = substr($moverse,0,strrpos($moverse,'/'));
}

if(
$moverse) $moverse = $moverse."/";

echo
$moverse.'<br>';

$handle=opendir($path.$moverse);

while (
$file = readdir($handle)) {
   if(
is_dir($path.$moverse.$file) && $file != ".") {
       if (
$file == ".." && $moverse == "") {
      
       } else {
           echo
"<a href='?moverse=".$moverse.$file."'>".$file."</a><br>";
       }
   } else if (
$file != ".") {
       echo
"<a href='".$path.$moverse.$file."'>".$file."</a><br>";
   }
}
?>
joey at alegria dot co dot jp
14-May-2004 07:41
After some consideration, this seems to be the most concise and elegent method I can devise for recursively traversing a directory (i.e. all subdirectories as well). It returns an Array containing all entries. It DOES NOT require global variables either.

To make it return only other directories or only files, insert one of the following where indicated:

DIR ONLY OPTION 1: if(is_dir($full_path)){ $list[]=$full_path; }

FILE ONLY OPTION 2: if(is_file($full_path)){ $list[}=$full_path; }

function make_tree($path){ //where $path is your source dir.
     $handle=opendir($path);
     while($a=readdir($handle)){
         if(!preg_match('/^\./',$a)){
               $full_path="$path/$a";
               $list[]=$full_path; // REPLACE WITH OPTION IF NEEDED.
               if(is_dir($full_path)){
                   $recursive=make_tree($full_path);
                   for($n=0; $n<count($recursive); $n++){
                         $list[]=$recursive[$n];
                   }
               }
         }
     }
     closedir($handle);
     return $list;
}

If conciseness is what you are after, the above is rock solid. However, beware of passing huge or unknown filesystem's paths as it can eat memory unless you impose a recursive level limit. The above can be very easily modified to limit recursive levels. See the below, limit-safe example.

function make_tree($path){ //where $path is your source dir.
     $handle=opendir($path);
     while($a=readdir($handle)){
         if(!preg_match('/^\./',$a)){
               $full_path="$path/$a";
               $list[]=$full_path;
               if((is_dir($full_path))&&(!preg_match('/(\/.+){6,}/',$full_path))){ //where {6,} is the maximum recursives
                   $recursive=make_tree($full_path);
                   for($n=0; $n<count($recursive); $n++){
                         $list[]=$recursive[$n];
                   }
               }
         }
     }
     closedir($handle);
     return $list;
}
turgon64 at hotmail dot com
25-Feb-2004 07:33
Just add my own script for manage directories

<?php
$path
= "./";
if(
$moverse) { chdir ($moverse); }
$handle=opendir($path);
while (
$file = readdir($handle)) {
   if(
is_dir($file)) {
       if(
$moverse){ $moverse = $moverse."/"; }
       echo
"<a href='?moverse=".$moverse.$file."'>".$file."</a><br>";
   }
   else
   {
       echo
"<a href='".getcwd()."/".$file."'>".$file."</a><br>";
   }
}
?>

I hope it will be usefull.
daevid at daevid dot com
21-Feb-2004 12:28
Just to add my own tip on the above recursive_dirlist()... I would suggest to make the last few lines:

   sort(&$getDirList_alldirs);
   sort(&$getDirList_allfiles);
   $retval['dirs'] = &$getDirList_alldirs;
   $retval['files'] = &$getDirList_allfiles;

otherwise your dirlisting may not be exactly the way you want, especially if you are operating on files in these dirs, and order may be a factor (as it is in my project ;-) )
phil at "DELETETHIS"blissnetworks dot net
10-Feb-2004 03:21
I searched around and couldn't find a decent function that JUST returned directories, not files.  I couldn't get the ones here to work so i wrote my own.

<?php
function read_dir($path){

   static
$dir_arr = array () ;
  
  
$handle=opendir($path);

   while (
$file = readdir($handle)) {           

         if (
$file != "." && $file != ".." && is_dir($path.$file)) {                   
          
          
$sub_dir = $path . $file . "/" ;
          
          
$dir_arr[] = $sub_dir ;       
          
          
read_dir($sub_dir);
          
       }
      
   }
  
   return
$dir_arr ;
 
}
?>
bosse at mellberg dot org
21-Jan-2004 06:12
I couldnt get the function by sc1n at yahoo dot com to work, so I modded it minorly to this:

function Fetch_File_Tree($start_directory)
{
   if( $dir = @opendir($start_directory) )
   {
       $tree = array();

       while( FALSE !== ($file = readdir($dir)) )
       {
           if($file != "." && $file != "..")
           {
               $absolute_file = $start_directory . $file;
              
               if (is_file($absolute_file)) $tree[] = $file;
               else if (is_dir($absolute_file)) Fetch_File_Tree($absolute_file."/");
           }
       }
   }
   else
   {
       return FALSE;
   }
   return $tree;
}

The @-sign is just for suppressing warnings.

Good luck!
sc1n at yahoo dot com
19-Jan-2004 03:04
The following function returns a tree of the directory structure from the given start point.

<?php

function Fetch_File_Tree($start_directory)
{
   if(
$dir = opendir($start_directory) )
   {
      
$tree = array();
      
       while(
FALSE !== ($file = readdir($dir)) )
       {
           if(
$file != "." && $file != "..")
           {
              
$absolute_file = $start_directory . $file;
              
is_file($absolute_file) ? $tree[] = $file : $tree[$file] =  Fetch_File_Tree($absolute_file . "/");
           }
       }
   }
   else
   {
       return
FALSE;
   }
   return
$tree;
}

?>
Ian Redden
16-Jan-2004 10:18
Heres mine modified from the original example:

function listdir($dir) {
   function ls_recursive($dir) {
       if (is_dir($dir))
       {
           $dirhandle=opendir($dir);
           while(($file = readdir($dirhandle)) !== false)
           {
               if (($file!=".")&&($file!="..")) {
                   $currentfile=$dir."/".$file;
                   if (!$i) $i = 0;
                   $dir_array[$i] = $currentfile;
                   $i++;
                   if(is_dir($currentfile)) {
                       ls_recursive($currentfile);
                   }
               }
           }
       }
       return $dir_array;
   }

   $dir_array = ls_recursive($dir);
   return $dir_array;
}
10-Oct-2003 10:12
get a list of files and directories recursivelly without the use of global variables.
the difference between this one and piccaso at gmx dot net's, is that this one returns files inside the subdirectories as well (with full path) :

function recursive_listdir($base) {
   static $filelist = array();
   static $dirlist = array();

   if(is_dir($base)) {
       $dh = opendir($base);
       while (false !== ($dir = readdir($dh))) {
           if (is_dir($base ."/". $dir) && $dir !== '.' && $dir !== '..') {
               $subbase = $base ."/". $dir;
               $dirlist[] = $subbase;
               $subdirlist = recursive_listdir($subbase);
           } elseif(is_file($base ."/". $dir) && $dir !== '.' && $dir !== '..') {
               $filelist[] = $base ."/". $dir;
           }
       }
       closedir($dh);
   }
   $array['dirs'] = $dirlist;
   $array['files'] = $filelist;
   return $array;
 }
arun at upress dot unm dot edu
08-Oct-2003 10:34
correction to piccaso at gmx dot net's

function recrusive_dirlist($base_dir)
<?
/*
This function retuns all directory and file names from the given directory.
Works recrusive. Based on ltena at gmx dot net's function.
*/
function recrusive_dirlist($base_dir)
{
global
$getDirList_alldirs,$getDirList_allfiles;
   function
getDirList($base)
   {
   global
$getDirList_alldirs,$getDirList_allfiles;
   if(
is_dir($base))
       {
          
$dh = opendir($base);
       while (
false !== ($dir = readdir($dh)))
           {
           if (
is_dir($base ."/". $dir) && $dir !== '.' && $dir !== '..') //note the change in this line
              
{
                  
$subs = $dir    ;
                  
$subbase = $base ."/". $dir;//note the change in this line
                  
$getDirList_alldirs[]=$subbase;
                  
getDirList($subbase);
               }
           elseif(
is_file($base ."/". $dir) && $dir !== '.' && $dir !== '..')//change in this line too
              
{
              
$getDirList_allfiles[]=$base ."/". $dir;//change in this line too
              
}
           }
          
closedir($dh);
       }
   }

getDirList($base_dir);
$retval['dirs']=$getDirList_alldirs;
$retval['files']=$getDirList_allfiles;
return
$retval;
}

// example usage:
echo '<pre>';
print_r(recrusive_dirlist('/home/computerdreams.at/cms/'));
echo
'</pre>';
/*
Prints out something like this:

Array
(
   [dirs] => Array
       (
           [0] => /home/computerdreams.at/cms/xoops-2.0.3/
           [1] => /home/computerdreams.at/cms/xoops-2.0.3/html/
           [2] => /home/computerdreams.at/cms/xoops-2.0.3/html/modules/
           [3] => /home/computerdreams.at/cms/xoops-2.0.3/html/modules/news/
           ...
           ...
       )

   [files] => Array
       (
           [0] => /home/computerdreams.at/cms/li
           [1] => /home/computerdreams.at/cms/lo
           [2] => /home/computerdreams.at/cms/tab
           [3] => /home/computerdreams.at/cms/tmp
           ...
           ...
       )

)

I downt know if this is the best way to do this.
If you find a better way, please drop me a note.

greez
[email protected]
*/
?>

I used the function without making any changes and did not get any output, no error though. then i realised the mistake and did the changes and got perfect output.

hope this helps someone in future.

Arun.
piccaso at gmx dot net
08-Sep-2003 07:17
<?
/*
This function retuns all directory and file names from the given directory.
Works recrusive. Based on ltena at gmx dot net's function.
*/
function recrusive_dirlist($base_dir)
{
global
$getDirList_alldirs,$getDirList_allfiles;
   function
getDirList($base)
   {
   global
$getDirList_alldirs,$getDirList_allfiles;
   if(
is_dir($base))
       {
          
$dh = opendir($base);
       while (
false !== ($dir = readdir($dh)))
           {
           if (
is_dir($base . $dir) && $dir !== '.' && $dir !== '..')
               {
                  
$subs = $dir    ;
                  
$subbase = $base . $dir . '/';
                  
$getDirList_alldirs[]=$subbase;
                  
getDirList($subbase);
               }
           elseif(
is_file($base . $dir) && $dir !== '.' && $dir !== '..')
               {
              
$getDirList_allfiles[]=$base . $dir;
               }
           }
          
closedir($dh);
       }
   }

getDirList($base_dir);
$retval['dirs']=$getDirList_alldirs;
$retval['files']=$getDirList_allfiles;
return
$retval;
}

// example usage:
echo '<pre>';
print_r(recrusive_dirlist('/home/computerdreams.at/cms/'));
echo
'</pre>';
/*
Prints out something like this:

Array
(
   [dirs] => Array
       (
           [0] => /home/computerdreams.at/cms/xoops-2.0.3/
           [1] => /home/computerdreams.at/cms/xoops-2.0.3/html/
           [2] => /home/computerdreams.at/cms/xoops-2.0.3/html/modules/
           [3] => /home/computerdreams.at/cms/xoops-2.0.3/html/modules/news/
           ...
           ...
       )

   [files] => Array
       (
           [0] => /home/computerdreams.at/cms/li
           [1] => /home/computerdreams.at/cms/lo
           [2] => /home/computerdreams.at/cms/tab
           [3] => /home/computerdreams.at/cms/tmp
           ...
           ...
       )

)

I downt know if this is the best way to do this.
If you find a better way, please drop me a note.

greez
[email protected]
*/
?>
de \ kibo \ niels
27-Aug-2003 02:53
Why, here's the millionth recursive directory listing script. The extra added bonus in this thing is, it lists the directories in a win-explorer-like fashion, with indentation according to hierarchical depth and such gizmos.

Using the variable $sf, you can control whether files should be displayed. If $sf == 0, only directories will be shown. This is useful if you just want to see the hierarchical structure of what's in that path.

The output must be encapsulated in "preformatted" tags, otherwise things will look wild. Directories are shown in "bold", the explorer-like watchamacallits that show you where you are, are "italic", so you'd best use CSS to overwrite the standard formatting so it looks good. I used this:
b {color:blue}
i {font-style:normal; color:gray}

This code can of course be greatly improved upon *hint* :)

<php?
function displaydir ($path, $depth) {
   if (($d = @opendir ($path)) === false) echo ('[Could not open path:]');
   else {
       while ($f = readdir ($d)) {
           if ($f != "." && $f != "..") {
               if (is_dir ($path . "/" . $f)) {
                   for ($i = 0; $i < $depth - 1; $i++) echo '<i>| </i>';
                   echo '<i>+-</i>';
                   echo "<b>$f</b>\n";
                   $depth++;
                   displaydir ($path . "/" . $f, $depth);
                   $depth--;
               } else {
                   if ($sf == 1) {
                       for ($i = 0; $i < $depth - 1; $i++) echo '<i>| </i>';
                       echo '<i>+-</i>';
                       echo "$f\n";
                   }
               }
           }
       }
       closedir ($d);
   }
}

displaydir ($url, 0);
?>
ltena at gmx dot net
23-Jul-2003 11:36
Recursive function to browse folders (Unix)

$base = '/home/';

function getDirList($base)
{
   if(is_dir($base)){
       $dh = opendir($base);
       while (false !== ($dir = readdir($dh))) {
           if (is_dir($base . $dir) && $dir !== '.' && $dir !== '..') {
               $subs = $dir    ;
               $subbase = $base . $dir . '/';
               print $subbase . "<br>";
               getDirList($subbase);
           } else {
               next;
           }
       }
       closedir($dh);
   } else {
       print "no es dir";
   }
}

getDirList($base);

Regards
Luis Tena O.
Mexico City
fabrizio - > effepi.system at inwind.it
21-May-2003 04:39
here a function that create an array with all the files and
 folders in the directory and in all the subdirectories

qui una funzione che crea un array con tutti i file e le cartelle
 nella directory ricercata e nelle sue subdirectories

i.e.:
dir1
 |-dir2
 |  |-file1
 |  |-dir3
 |-file2

$array[dir1][dir2][0] = file1
$array[dir1][dir2][dir3]=NULL  //no files inside
$array[dir1][0] = file2

function expFp($folder = ".", $filetype = "")
   {
   $currdir=getcwd();
   if ($folder)
       @chdir("$folder");
   $dh = opendir(".");
     while(false !== ($file = readdir($dh)))
       {
       // insert all the files in an array
       if(is_file($file) &&
             ( strtoupper( substr( $file,(-1*strlen($filetype))))==strtoupper($filetype)))   
           $a_files[] = $file;
       //htm is a folder that you don't want to use
       if (is_dir($file) && $file!="." && $file!=".." && $file!="htm")
           $a_files[$file] = expFp($file, $filetype);
       }
   closedir($dh);
   chdir($currdir);
//    if (is_array($a_files))
//        array_multisort($a_files);
   return $a_files;
   }
johnpipi at hotmail dot com
02-Mar-2003 06:22
Here is a function that returns an array of all files (filenames) from inputted directory.

   function getDirFiles($dirPath)
   {
     if ($handle = opendir($dirPath))
     {
         while (false !== ($file = readdir($handle)))
             if ($file != "." && $file != "..")
                 $filesArr[] = trim($file);
                
         closedir($handle);
     } 
    
     return $filesArr;   
   }
admin[ at T]networkessence dot net
21-Aug-2002 12:41
This script will count lines of code that do not begin with // or are not blank space.  It's very approximate because it will include /* */ comments and will also include lines that start with blank space and then //.  It's a start though (it's recursive, so don't use this with a directory structure that includes symbolic links).  This will recursively count all the lines of files that end with .php.  You can change .php to whatever, and also change the guidelines as to whether a line qualifies as a comment or not (look around the !="//" part)

$i=0;

function getDirList ($dirName) {
       global $i;
       $d = dir($dirName);
               while($entry = $d->read()) {
                       if ($entry != "." && $entry != "..") {
                               if (is_dir($dirName."/".$entry)) {
                                       getDirList($dirName."/".$entry);
                               } else if(substr($entry, -4)=='.php') {
                                       if($read_file = file($dirName.'/'.$entry))
                                               foreach($read_file as $line)
                                                       if(($line!="\n") && (substr($line, 0, 2)!="//"))
                                                               $i++;
                                       echo $dirName."/".$entry."\n";
                               }
                       }
               }
       $d->close();
}

getDirList("./path/to/files");

echo $i;
erere CHIOCCIOLINA iname PUNTO com
17-Aug-2002 01:40
In [email protected]'s function list_dir($dirname):

if(is_dir($dirname.$file))
list_dir($dirname.$file.'\\');

should become:

if(is_dir($dirname.$file))
$result_array[]=list_dir($dirname.$file.'\\');

or recursion will be done, but no subdirs will be pushed into the $result_array.

Ernesto
tapani
07-Aug-2002 01:54
shell_exec this

ls -la '$dir'|wc -l|sed 's/^ *//;'

to get number of files in dir
Bill at Example dot net
23-May-2002 07:20
Just a side note....not really php'ish

$mstrng = shell_exec('du -sc /usr/local/apache/www');
print "$mstrng";

Will get you the size of a directory, including all of its sub dirs and files within.
ben AT tech-space DOT net
23-May-2002 06:10
//lists all files in a directory with a given file name convention

function list_dir($file_name_convention) {
  switch ($file_name_convention) {
   case 'dated_reports':
     //matches files like '5_23_2002.html'
     $this_regexp = "/[0-9]{1,}_[0-9]{1,}_[0-9]{4,}/";
     break;
     //add more cases of file name conventions
  }
  $this_dir = dir('.');
  if ($this_regexp != null) {
   while ($file = $this_dir->read()) {
     if (preg_match($this_regexp, $file)) {
       $result_array[] = $file;
     }
   }
  }
  return $result_array;
}

<dio_writechdir>
 Last updated: Sun, 27 Feb 2005
show source | credits | sitemap | contact | advertising | mirror sites 
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: /
Last updated: Mon Mar 14 08:13:06 2005 Local time zone must be set--see zic manual page