如何使用PHP计算目录中的文件数?

How to count the number of files in a directory using PHP?

Please answer for the following things:

1. Recursive Search: The directory (which is being searched) might be having several other directories and files.

2. Non-Recursive Search: All the directories should be ignored which are inside the directory that is being searched. Only files to be considered.

I am having the following code, but looking for a better solution.

<?php

     $files = array();
     $dir = opendir('./items/2/l');
     while(($file = readdir($dir)) !== false)
     {
          if($file !== '.' && $file !== '..' && !is_dir($file))
          {
               $files[] = $file;
          }
     }
     closedir($dir);
     //sort($files);
     $nooffiles = count($files);
?>

non-recrusive:

$dir = opendir('dir/');
$i = 0;
while (false !== ($file = readdir($dir))){
    if (!in_array($file, array('.', '..') and !is_dir($file)) $i++;
}

echo "There were $i files";

recrusive:

function crawl($dir){

    $dir = opendir($dir);
    $i = 0;
    while (false !== ($file = readdir($dir)){
            if (is_dir($file) and !in_array($file, array('.', '..'))){

            $i += crawl($file);
        }else{
            $i++;
        }

    }
    return $i;
}
$i = crawl('dir/');
echo "There were $i files";

Might be useful for you:

http://www.php.net/manual/en/class.dir.php

http://www.php.net/manual/en/function.is-file.php

But, i think, there is no other good solutions.

Something like this might work:
(might need to add some checks for '/' for the $dir.$file concatenation)

$files = array();
$dir = './items/2/l';

countFiles($dir, $files); // Recursive
countFiles($dir, $files, false); // Not recursive;

var_dump(count($files));

function countFiles($directory, &$fileArray, $recursive = true){
    $currDir = opendir($directory);    
    while(($file = readdir($dir)) !== false)
    {
        if(is_dir($file) && $recursive){
            countFiles($directory.$fileArray, $saveArray);
        }
        else if($file !== '.' && $file !== '..' && !is_dir($file))
        {
            $fileArray[] = $file;
        }
    }
}

Rather than posting code for you, I would provide the outline of what you should do as you seem to have the basic code already.

Place your code in a function. Have two parameters ($path, $recursive = FALSE) and within your code, separate the is_dir() and if that's true and the recursive flag is true, then pass the new path (path to the current file) back to the function (self reference).

Hope this helps you learn, rather than copy paste :-)

Recursive:

function count_files($path) {

// (Ensure that the path contains an ending slash)

$file_count = 0;

$dir_handle = opendir($path);

if (!$dir_handle) return -1;

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

    if ($file == '.' || $file == '..') continue;

    if (is_dir($path . $file)){      
        $file_count += count_files($path . $file . DIRECTORY_SEPARATOR);
    }
    else {
        $file_count++; // increase file count
    }
}

closedir($dir_handle);

return $file_count;

}

Non-Recursive:

$directory = ".. path/";
if (glob($directory . "*.") != false)
{
 $filecount = count(glob($directory . "*."));
 echo $filecount;
}
else
{

 echo 0;
}

Recursive:

$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
$count = 0;
while($it->next()) $count++;

Courtesy of Russell Dias

You can use the SPL DirectoryIterator to do this in a non-recursive (or with a recursive iterator in a recursive) fashion:

iterator_count(new DirectoryIterator($directory));

It's good to note that this will not just count regular files, but also directories, dot files and symbolic links. For regular files only, you can use:

$directory = new DirectoryIterator($directory);
$count = 0;
foreach($directory as $file ){ $count += ($file->isFile()) ? 1 : 0;}

PHP 5.4.0 also offers:

iterator_count(new CallbackFilterIterator($directory, function($current) { return $current->isFile(); }));
$dir = opendir('dir/');
$i = 0;
while (false !== ($file = readdir($dir))){
    if (!in_array($file, array('.', '..' ))and (!is_dir($file)))
    $i++;
}

echo "There were $i files";

Most of the mentioned ways for "Non-Recursive Search" work, though it can be shortened using PHP's glob filesystem function.

It basically finds pathnames matching a pattern and thus can be used as:

$count = 0;
foreach (glob('path\to\dir\*.*') as $file) {
    $count++;
}

The asterisk before the dot denotes the filename, and the one after denotes the file extension. Thus, its use can further be extended to counting files with specific filenames, specific extensions or both.