A very flexible function to recursively list all files in a directory with the option to perform a custom set of actions on those files and/or include extra information about them in the returned data.
----------
SYNTAX:
$array = process_dir ( $dir , $recursive = FALSE )
$dir (STRING) = Directory to process
$recursive (BOOLEAN) = [Optional] Recursive if set to TRUE
RETURN VALUES:
The function returns an indexed array, one entry for every file. Each entry is an associative array, containing the basic information 'filename' (name of file) and 'dirpath' (directory component of path to file), and any additional keys you configure. Returns FALSE on failure.
----------
To allow you to configure another key, the entry for each file is stored in an array, "$entry" for each iteration. You can easily return any additional data for a given file using $entry['keyname'] = ... (Note that this data can be any variable type - string, bool, float, resource etc)
There is a string variable "$path" available, which contains the full path of the current file, relative to the initial "$dir" supplied at function call. This data is also available in it's constituent parts, "$dir" and "$file". Actions for each file can be constructed on the basis of these variables. The variables "$list", "$handle" and "$recursive" should not be used within your code.
----------
Simply insert you code into the sections indicated by the comments below and your away!
The following example returns filename, filepath, and file modified time (in a human-readable string) for all items, filesize for all files but not directories, and a resource stream for all files with 'log' in the filename (but not *.log files).
<?php
function process_dir($dir,$recursive = FALSE) {
if (is_dir($dir)) {
for ($list = array(),$handle = opendir($dir); (FALSE !== ($file = readdir($handle)));) {
if (($file != '.' && $file != '..') && (file_exists($path = $dir.'/'.$file))) {
if (is_dir($path) && ($recursive)) {
$list = array_merge($list, process_dir($path, TRUE));
} else {
$entry = array('filename' => $file, 'dirpath' => $dir);
//---------------------------------------------------------//
// - SECTION 1 - //
// Actions to be performed on ALL ITEMS //
//----------------- Begin Editable ------------------//
$entry['modtime'] = filemtime($path);
//----------------- End Editable ------------------//
do if (!is_dir($path)) {
//---------------------------------------------------------//
// - SECTION 2 - //
// Actions to be performed on FILES ONLY //
//----------------- Begin Editable ------------------//
$entry['size'] = filesize($path);
if (strstr(pathinfo($path,PATHINFO_BASENAME),'log')) {
if (!$entry['handle'] = fopen($path,r)) $entry['handle'] = "FAIL";
}
//----------------- End Editable ------------------//
break;
} else {
//---------------------------------------------------------//
// - SECTION 3 - //
// Actions to be performed on DIRECTORIES ONLY //
//----------------- Begin Editable ------------------//
//----------------- End Editable ------------------//
break;
} while (FALSE);
$list[] = $entry;
}
}
}
closedir($handle);
return $list;
} else return FALSE;
}
$result = process_dir('C:/webserver/Apache2/httpdocs/processdir',TRUE);
// Output each opened file and then close
foreach ($result as $file) {
if (is_resource($file['handle'])) {
echo "\n\nFILE (" . $file['dirpath'].'/'.$file['filename'] . "):\n\n" . fread($file['handle'], filesize($file['dirpath'].'/'.$file['filename']));
fclose($file['handle']);
}
}
?>
readdir
(PHP 4, PHP 5)
readdir — Lit une entrée du dossier
Description
readdir() retourne le nom du fichier suivant dans le dossier identifié par dir_handle . Les noms sont retournés dans l'ordre qu'ils sont enregistrés dans le système de fichiers.
Liste de paramètres
- dir_handle
-
La ressource de dossier ouverte précédemment avec opendir(). Si la ressource de dossier n'est pas spécifiée, la dernière ressource ouverte avec la fonction opendir() sera utilisée.
Valeurs de retour
Retourne le nom du fichier en cas de réussite ou FALSE en cas d'échec.
Cette fonction peut retourner FALSE, mais elle peut aussi retourner une valeur équivalent à FALSE comme 0 ou "". Veuillez lire la section sur les booléens pour plus d'informations. Utilisez l'opérateur === pour tester la valeur de retour exacte de cette fonction.
Exemples
Exemple #1 Liste de tous les fichiers dans le répertoire
Notez la façon dont la valeur de retour de dir() est vérifiée dans l'exemple suivant. Nous testons si la valeur est identique (égale et de même type que -- voyez opérateurs de comparaison pour plus de détails) FALSE sinon, toute entrée dans le nom serait évalué à FALSE causera l'arrêt de la boucle (exemple, un répertoire nommé 0).
<?php
// Notez que !== n'existait pas avant 4.0.0-RC2
if ($handle = opendir('/chemin/vers/fichiers')) {
echo "Directory handle: $handle\n";
echo "Files:\n";
/* Ceci est la façon correcte de traverser un dossier. */
while (false !== ($file = readdir($handle))) {
echo "$file\n";
}
/* Ceci est la MAUVAISE façon de traverser un dossier. */
while ($file = readdir($handle)) {
echo "$file\n";
}
closedir($handle);
}
?>
Exemple #2 Liste de tous les fichiers dans le répertoire courant et enlève les . et ..
<?php
if ($handle = opendir('.')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
echo "$file\n";
}
}
closedir($handle);
}
?>
readdir
17-May-2009 02:39
08-May-2009 07:08
Thought I would include what I wrote to get a random image from a directory.
<?php
$image_dir = 'images';
$count = 0;
if ($handle = opendir($image_dir)) {
$retval = array();
while (false !== ($file = readdir($handle))) {
if (($file <> ".") && ($file <> "..")) {
$retval[$count] = $file;
$count = $count + 1;
}
}
closedir($handle);
}
shuffle($retval);
$current_image = $retval[0];
?>
[NOTE BY danbrown AT php DOT net: Contains a bugfix/typofix inspired by 'ffd8' on 19-JUN-09.]
23-Apr-2009 05:07
I was using Kim's code to count the number of files in several different folders, one after another. I was putting the total of each function call into seperate variables, but the function kept a RUNNING total from each separate call - until I removed the static $counter declaration inside the function. Might save someone some hair pulling.
15-Mar-2009 07:37
This function is used to display random image i.e. at header position of a site. It reads the whole directory and then randomly print the image. I think it may be useful for someone.
<?php
if ($handle = opendir('images/')) {
$dir_array = array();
while (false !== ($file = readdir($handle))) {
if($file!="." && $file!=".."){
$dir_array[] = $file;
}
}
echo $dir_array[rand(0,count($dir_array)-1)];
closedir($handle);
}
?>
20-Feb-2009 09:56
Of course there is an error in my previous post!
<? $r = dir_size($p, $recursive, $searchext); ?>
should be
<? $r = dir_count($p, $recursive, $searchext); ?>
20-Feb-2009 08:11
Both Kim Christensen and Joris DECOMBE include a $recursive var in their functions, but neither one checks for it. As a result, both functions are recursive regardless of the var setting -- and by default. Also, Joris, you assume there will be a search extension - what if we don't want to filter? Unit test, people. This version also does away with the need for static vars.
/**
* Return the count and filesize for files in a directory
*
* @param string $dir
* @param boolean $recursive
* @param string $searchext
* @return array | false
*
*/
function dir_count($dir, $recursive=false, $searchext=false) {
if(substr($dir,-1)==".") $dir = substr($dir,0,-1);
if(!is_dir($dir)) {
trigger_error("Not a directory: {$dir}.");
return false;
}
if(!$d = opendir($dir)) {
trigger_error("Unable to open directory: {$dir}");
return false;
}
while(($i = readdir($d)) !== false) {
if(($i == '.') || ($i == '..')) continue;
$e = array_pop(explode(".",$i));
$p = $dir."/".$i;
if(is_file($p)) {
if(($searchext !== false) && ($e != $searchext)) continue;
$c++;
$s += filesize($p);
} elseif(is_dir($p) && $recursive) {
$r = dir_size($p, $recursive, $searchext);
$c += $r[0];
$s += $r[1];
}
}
closedir($d);
return array($c,$s);
}
11-Feb-2009 05:45
I couldn't easily find a way to recursively search and list all the files and directories in a directory. So here's a stab at it for anyone else who's looking.
<?php
//define the path as relative
$path = "path to directory";
$webpath ="the url you want to place before your filename/";
//using the opendir function
$dir_handle = @opendir($path) or die("Unable to open $path");
echo "Directory Listing of $path<br/>";
list_dir($dir_handle,$path);
function list_dir($dir_handle,$path)
{
// print_r ($dir_handle);
echo "<ol>";
//running the while loop
while (false !== ($file = readdir($dir_handle))) {
$dir =$path.'/'.$file;
if(is_dir($dir) && $file != '.' && $file !='..' )
{
$handle = @opendir($dir) or die("undable to open file $file");
echo "<li><a href='$webpath.$file'>$file</a></li>";
list_dir($handle, $dir);
}elseif($file != '.' && $file !='..')
{
echo "<li><a href='$webpath.$file'>$file</a></li>";
}
}
echo "</ol>";
//closing the directory
closedir($dir_handle);
}
?>
26-Dec-2008 03:24
Little modification of Kim Christensen's num_files function:
Added a file filter (by extension) parameter, and returns an array with the total number of files and the total size (in bytes).
Example:
You want to know how many .avi files you've got on a file server, and what size it costs:
<?php
print_r(num_files("//fileserver/share", true, "avi"))
/*
returns array(
0 => int(number of files),
1 => float(total size in bytes)
)
*/
?>
The function:
<?php
function num_files($dir, $recursive=false, $searchext, $counter=0, $totalsize=0) {
static $counter;
static $totalsize;
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if ($file != "." && $file != "..") {
$fileChunks = array_reverse(explode(".", $file));
$ext = $fileChunks[0];
if (is_file($dir."/".$file)&&(strtolower($ext) == strtolower($searchext))) {
$counter++;
$totalsize = $totalsize + filesize($dir."/".$file);
}
else if (is_dir($dir."/".$file)) {
num_files($dir."/".$file, $recursive, $searchext, $counter);
}
}
}
closedir($dh);
}
}
return array($counter,$totalsize);
}
?>
18-Dec-2008 04:59
Below will return an array of file names and folders in directory
<?php
function ReadFolderDirectory($dir = "root_dir/here")
{
$listDir = array();
if($handler = opendir($dir)) {
while (($sub = readdir($handler)) !== FALSE) {
if ($sub != "." && $sub != ".." && $sub != "Thumb.db") {
if(is_file($dir."/".$sub)) {
$listDir[] = $sub;
}elseif(is_dir($dir."/".$sub)){
$listDir[$sub] = $this->ReadFolderDirectory($dir."/".$sub);
}
}
}
closedir($handler);
}
return $listDir;
}
?>
30-Sep-2008 08:09
@mesyash_one at wp dot pl
Don´t use
<?php
$fileChunks = explode(".", $file);
$ext= $fileChunks[1];
?>
It will create a notice if there is a file without extension. And if theres a file with 2 dots the result will be wrong.
Better use
<?php
$fileChunks = array_reverse(explode(".", $file));
$ext= $fileChunks[0];
?>
and check for files without extension.
27-Sep-2008 12:25
<?php
//getting all files of desired extension from the dir using explode
$desired_extension = 'pdf'; //extension we're looking for
$dirname = "uploads/";
$dir = opendir($dirname);
while(false != ($file = readdir($dir)))
{
if(($file != ".") and ($file != ".."))
{
$fileChunks = explode(".", $file);
if($fileChunks[1] == $desired_extension) //interested in second chunk only
{
echo 'a href="uploads/'.$file.'" target="_blank"> '.$file.'</a></br>';
}
}
}
closedir($dir);
?>
11-Jul-2008 06:20
A simple directory browser... that handles the windows charset in filenames (it should work for every iso-8859-1 characters).
<?php
$basepath = realpath("./pub/"); // Root directory
$path = realpath($basepath.$_GET["path"]); // Requested path
$relativepath = "./".substr_replace( $path, "", 0, strlen( $basepath ) );
if( "/" == substr( $relativepath, -1 )) { // Remove the trailing slash
$relativepath = substr( $relativepath, 0, -1 );
}
$dh = opendir( $path );
while( false !== ($file = readdir( $dh ))) {
if("." == $file) {continue;}
// converts the filename to utf8
$file_utf8 = iconv( "iso-8859-1", "utf-8", $file );
// encode the path ('path' part: already utf8; 'filename' part: still iso-8859-1)
$link = str_replace( "%2F", "/", rawurlencode( "{$relativepath}/" )) . rawurlencode( utf8_decode( "{$file_utf8}" ));
if( is_dir( "{$path}/{$file}" )) {
echo "<a href=\"?path={$link}&\">{$file_utf8}</a><br/>"
} else {
echo "<a href=\"{$link}&\">{$file_utf8}</a><br/>"
}
}
}
?>
05-May-2008 03:14
Handy little function that returns the number of files (not directories) that exists under a directory.
Choose if you want the function to recurse through sub-directories with the second parameter -
the default mode (false) is just to count the files directly under the supplied path.
<?php
/**
* Return the number of files that resides under a directory.
*
* @return integer
* @param string (required) The directory you want to start in
* @param boolean (optional) Recursive counting. Default to FALSE.
* @param integer (optional) Initial value of file count
*/
function num_files($dir, $recursive=false, $counter=0) {
static $counter;
if(is_dir($dir)) {
if($dh = opendir($dir)) {
while(($file = readdir($dh)) !== false) {
if($file != "." && $file != "..") {
$counter = (is_dir($dir."/".$file)) ? num_files($dir."/".$file, $recursive, $counter) : $counter+1;
}
}
closedir($dh);
}
}
return $counter;
}
// Usage:
$nfiles = num_files("/home/kchr", true); // count all files that resides under /home/kchr, including subdirs
$nfiles = num_files("/tmp"); // count the files directly under /tmp
?>
15-Apr-2008 11:13
This is a nice quick full dir read - sorry for my bad english ;)
function ReadDirs($dir,$em){
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && $file != "Thumb.db") {
if(is_dir($dir.$file)){
echo $em."» ".$file.'<br>';
ReadDirs($dir.$file."/",$em." ");
}
}
}
closedir($handle);
}
}
18-Mar-2008 05:03
Here's an easy way to output the contents as a list of download links.
<?php
$count = 0;
if ($handle = opendir('.')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {$count++;
print("<a href=\"".$file."\">".$file."</a><br />\n");
}
}
echo '<br /><br /><a href="..">Return</a>';
closedir($handle);
}
?>
and simply use $count to list the overall number of files.
15-Nov-2007 09:15
Oops, made a few syntactical errors in the last example of getting only the final directory paths from a root dir. PHP 4 OO.
var $rootDir = '/SOME DIRECTORY';
print_r($this->getFinalDirs($this->rootDir));
function getFinalDirs($root)
{
return $this->getNext($root);
}
function getNext($path)
{
static $dirs = array();
$handle = opendir($path);
if($handle)
{
while (false!==($dir=readdir($handle)))
{
if ($dir!='.'&&$dir!='..'&& $dir!='.DS_Store')
{
if(is_dir($path.'/'.$dir))
{
$this->getNext($path.'/'.$dir);
} else
{
array_push($dirs, $path);
break;
}
}
}
}
return $dirs;
}
14-Nov-2007 03:54
for ( $files = array(); ( $file = readdir( $handle )) !== false; $files[] = $file );
12-Sep-2007 05:23
Yet another view files by extension
/* NOTE:
* /a-d = do not include directories
* /b = show files in bare mode ( no dates or filesize )
*/
<?php
$dir = '.\\img\\'; // reminder: escape your slashes
$filetype = "*.png";
$filelist = shell_exec( "dir {$dir}{$filetype} /a-d /b" );
$file_arr = explode( "\n", $filelist );
array_pop( $file_arr ); // last line is always blank
print_r( $file_arr );
?>
21-Aug-2007 11:09
The following code is a bit nasty, it can be used to remove all files generated by apache.
You're not a root user on a system, but you sometimes need to remove all files generated by apache in a certain directory. You may use this after replacing 'bbs' at the bottom with 'directory' you want.
It tries to remove all files in a directory, but it can't unless it has an ownership. it doesn't check the ownership or permission.
<?php
function remove($dirname = '.')
{
if (is_dir($dirname))
{
echo "$dirname is a directory.<br />";
if ($handle = @opendir($dirname))
{
while (($file = readdir($handle)) !== false)
{
if ($file != "." && $file != "..")
{
echo "$file<br />";
$fullpath = $dirname . '/' . $file;
if (is_dir($fullpath))
{
remove($fullpath);
@rmdir($fullpath);
}
else
{
@unlink($fullpath);
}
}
}
closedir($handle);
}
}
}
remove('bbs');
?>
20-Aug-2007 07:06
I haven't tested this yet, but it seems like it'll do just fine if you need files of a certain extension:
$dh = opendir($options['inputDir']);
$files = array();
while (($filename = readdir($dh)) !== false)
{
if (substr($filename, strrpos($filename, '.')) == $options['inputExt'])
{
$files[] = $filename;
}
}
closedir($dh);
12-Jul-2007 05:25
PLease disregard my last two posts. For the last one, if you're looking for files with .php extension, you also get files with any extension that ends with 'p'. I wrote the function in quite a haste and now I am too busy to fix it - so don't use it! it's no good.
12-Jul-2007 03:53
Sorry,
In my last post, if you only want to list files with certain extensions, then see how many letters this extension is, add one to it, and subtract it from the strlen of the file name. Review script below for details.
12-Jul-2007 03:27
Responding to:
johan dot mickelin at gmail dot com
31-May-2007 07:52
-------------------------------------------------------
If you want to list only a certain filetype, this case only jpg and gif files in an image directory
$dir = opendir ("../images");
while (false !== ($file = readdir($dir))) {
if (strpos($file, '.gif',1)||strpos($file, '.jpg',1) ) {
echo "$file <br />";
}
}
-----------------------------------------------------------------
This function would also echo files that have .gif or .jpg in their names such as myFile.gif.php (I don't know why I'd name a file like that, but I am just making a point, that's all folks!)
Perhaps a more exact way is to do the following:
...
while (false !== ($file = readdir($dir))) {
$lenOfFileName = strlen($file);
$extOffsetPos = $lenOfFileName - 5;
if (strpos($file, '.gif', $extOffsetPos) ||
strpos($file, '.jpg',$extOffsetPos) ) {
echo "$file <br />";
}
...
If your extensions are more than three letters, then increase the 5 to 6 (e.g. aspx) to 7 (e.g. php51) or whatever.
01-Jun-2007 02:52
If you want to list only a certain filetype, this case only jpg and gif files in an image directory
$dir = opendir ("../images");
while (false !== ($file = readdir($dir))) {
if (strpos($file, '.gif',1)||strpos($file, '.jpg',1) ) {
echo "$file <br />";
}
}
28-May-2007 01:42
code:
<?php
function permission($filename)
{
$perms = fileperms($filename);
if (($perms & 0xC000) == 0xC000) { $info = 's'; }
elseif (($perms & 0xA000) == 0xA000) { $info = 'l'; }
elseif (($perms & 0x8000) == 0x8000) { $info = '-'; }
elseif (($perms & 0x6000) == 0x6000) { $info = 'b'; }
elseif (($perms & 0x4000) == 0x4000) { $info = 'd'; }
elseif (($perms & 0x2000) == 0x2000) { $info = 'c'; }
elseif (($perms & 0x1000) == 0x1000) { $info = 'p'; }
else { $info = 'u'; }
// владелец
$info .= (($perms & 0x0100) ? 'r' : '-');
$info .= (($perms & 0x0080) ? 'w' : '-');
$info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-'));
// группа
$info .= (($perms & 0x0020) ? 'r' : '-');
$info .= (($perms & 0x0010) ? 'w' : '-');
$info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-'));
// все
$info .= (($perms & 0x0004) ? 'r' : '-');
$info .= (($perms & 0x0002) ? 'w' : '-');
$info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-'));
return $info;
}
function dir_list($dir)
{
if ($dir[strlen($dir)-1] != '/') $dir .= '/';
if (!is_dir($dir)) return array();
$dir_handle = opendir($dir);
$dir_objects = array();
while ($object = readdir($dir_handle))
if (!in_array($object, array('.','..')))
{
$filename = $dir . $object;
$file_object = array(
'name' => $object,
'size' => filesize($filename),
'perm' => permission($filename),
'type' => filetype($filename),
'time' => date("d F Y H:i:s", filemtime($filename))
);
$dir_objects[] = $file_object;
}
return $dir_objects;
}
?>
call:
<?php
print_r(dir_list('/path/to/you/dir/'));
?>
output sample:
Array
(
[0] => Array
(
[name] => api
[size] => 0
[perm] => drwxrwxrwx
[type] => dir
[time] => 28 May 2007 01:55:02
)
[1] => Array
(
[name] => classes
[size] => 0
[perm] => drwxrwxrwx
[type] => dir
[time] => 26 May 2007 00:56:44
)
[2] => Array
(
[name] => config.inc.php
[size] => 143
[perm] => -rw-rw-rw-
[type] => file
[time] => 26 May 2007 13:13:19
)
[3] => Array
(
[name] => index.php
[size] => 131
[perm] => -rw-rw-rw-
[type] => file
[time] => 26 May 2007 22:15:18
)
[4] => Array
(
[name] => modules
[size] => 0
[perm] => drwxrwxrwx
[type] => dir
[time] => 28 May 2007 00:47:40
)
[5] => Array
(
[name] => temp
[size] => 0
[perm] => drwxrwxrwx
[type] => dir
[time] => 28 May 2007 04:49:33
)
)
15-May-2007 03:36
<?php
// Sample function to recursively return all files within a directory.
// http://www.pgregg.com/projects/php/code/recursive_readdir.phps
Function listdir($start_dir='.') {
$files = array();
if (is_dir($start_dir)) {
$fh = opendir($start_dir);
while (($file = readdir($fh)) !== false) {
# loop through the files, skipping . and .., and recursing if necessary
if (strcmp($file, '.')==0 || strcmp($file, '..')==0) continue;
$filepath = $start_dir . '/' . $file;
if ( is_dir($filepath) )
$files = array_merge($files, listdir($filepath));
else
array_push($files, $filepath);
}
closedir($fh);
} else {
# false if the function was called with an invalid non-directory argument
$files = false;
}
return $files;
}
$files = listdir('.');
print_r($files);
?>
14-May-2007 09:41
Here is an updated version of preg_find() [which has been linked from the glob() man page for years] - this function should provide most of what you want back from reading files, directories, different sorting methods, recursion, and perhaps most powerful of all the ability to pattern match with a PCRE regex.
You can get preg_find here: http://www.pgregg.com/projects/php/preg_find/preg_find.php.txt
or if you prefer colourful .phps format: http://www.pgregg.com/projects/php/preg_find/preg_find.phps
or scoll down to the end of this note.
I wrote several examples on how to use it on my blog at: http://www.pgregg.com/forums/viewtopic.php?tid=73
simple glob() type replacement:
$files = preg_find('/./', $dir);
recursive?
$files = preg_find('/./', $dir, PREG_FIND_RECURSIVE);
pattern match? find all .php files:
$files = preg_find('/\.php$/D', $dir, PREG_FIND_RECURSIVE);
sorted alphabetically?
$files = preg_find('/\.php$/D', $dir, PREG_FIND_RECURSIVE|PREG_FIND_SORTKEYS);
sorted in by filesize, in descending order?
$files = preg_find('/./', $dir,
PREG_FIND_RECURSIVE|PREG_FIND_RETURNASSOC |PREG_FIND_SORTFILESIZE|PREG_FIND_SORTDESC);
$files=array_keys($files);
sorted by date modified?
$files = preg_find('/./', $dir,
PREG_FIND_RECURSIVE|PREG_FIND_RETURNASSOC |PREG_FIND_SORTMODIFIED);
$files=array_keys($files);
Ok, the PHP note says my note is too long, so please click on one of the above links to get it.
04-Jul-2002 08:22
It should work, but it'll be better to read section 13.1.3 Cache-control Mechanisms of RFC 2616 available at http://rfc.net/rfc2616.html before you start with confusing proxies on the way from you and the client.
Reading it is the best way to learn how proxies work, what should you do to modify cache-related headers of your documents and what you should never do again. :-)
And of course not reading RFCs is the best way to never learn how internet works and the best way to behave like Microsoft corp.
Have a nice day!
Jirka Pech
10-Apr-2002 12:41
Someone mentioned the infinite recursion when a symbolic link was found...
tip: is_link() is a nice function :)
