使用PHP递归计数文件

时间:2009-03-12 23:49:30

标签: php recursion count

对于newb和我的Google-Fu的简单问题让我失望。使用PHP,如何计算给定目录中的文件数,包括任何子目录(以及它们可能具有的任何子目录等)?例如如果目录结构如下所示:

/Dir_A/  
/Dir_A/File1.blah  
/Dir_A/Dir_B/  
/Dir_A/Dir_B/File2.blah  
/Dir_A/Dir_B/File3.blah  
/Dir_A/Dir_B/Dir_C/  
/Dir_A/Dir_B/Dir_C/File4.blah  
/Dir_A/Dir_D/  
/Dir_A/Dir_D/File5.blah

对于“./Dir_A”,脚本应以'5'返回。

我拼凑了以下内容,但它并没有完全回复正确答案,我不确定原因:

function getFilecount( $path = '.', $filecount = 0, $total = 0 ){  
    $ignore = array( 'cgi-bin', '.', '..', '.DS_Store' );  
    $dh = @opendir( $path );  
    while( false !== ( $file = readdir( $dh ) ) ){  
        if( !in_array( $file, $ignore ) ){  
            if( is_dir( "$path/$file" ) ){  
                $filecount = count(glob( "$path/$file/" . "*"));  
                $total += $filecount;  
                echo $filecount; /* debugging */
                echo " $total"; /* debugging */
                echo " $path/$file
"; /* debugging */ getFilecount( "$path/$file", $filecount, $total); } } } return $total; }

我非常感谢任何帮助。

6 个答案:

答案 0 :(得分:18)

这应该可以解决问题:

function getFileCount($path) {
    $size = 0;
    $ignore = array('.','..','cgi-bin','.DS_Store');
    $files = scandir($path);
    foreach($files as $t) {
        if(in_array($t, $ignore)) continue;
        if (is_dir(rtrim($path, '/') . '/' . $t)) {
            $size += getFileCount(rtrim($path, '/') . '/' . $t);
        } else {
            $size++;
        }   
    }
    return $size;
}

答案 1 :(得分:15)

使用SPL,然后查看是否仍然出现错误。

RecursiveDirectoryIterator

用法示例:

<?php

$path = realpath('/etc');

$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
    echo "$name\n";
}

?>

这将打印$ path下的所有文件和目录的列表(包括$ path ifself)。如果要省略目录,请删除RecursiveIteratorIterator :: SELF_FIRST部分。

然后使用isDir()

答案 2 :(得分:2)

基于安德鲁的答案......

    $path = realpath('my-big/directory');
    $objects = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path),
        RecursiveIteratorIterator::SELF_FIRST
    );
    $count=iterator_count($objects);
    echo number_format($count); //680,642 wooohaah!

就像我能够数数(不列出)数千&amp;数千个文件。实际上不到4.6秒的680,642个文件;)

答案 3 :(得分:0)

为什么要传递$ filecount?没有使用[传入]值;唯一的用法是“$ total + = $ filecount”,你就是在此之前重写$ filecount。

当函数遇到常规(非目录)文件时,你会错过这种情况。

编辑:我刚注意到对glob()的调用。这不是必需的。无论如何,您的函数以递归方式触摸整个目录树中的每个文件。见@Paolo Bergantino的回答。

答案 4 :(得分:0)

Paolo Bergantino几乎带着他的代码,但该功能仍然会计算.DS_Store文件,因为他拼错了它。正确的代码

function getFileCount($path) {
    $size = 0;
    $ignore = array('.','..','cgi-bin','.DS_Store');
    $files = scandir($path);
    foreach($files as $t) {
        if(in_array($t, $ignore)) continue;
        if (is_dir(rtrim($path, '/') . '/' . $t)) {
            $size += getFileCount(rtrim($path, '/') . '/' . $t);
        } else {
            $size++;
        }   
    }
    return $size;
}

答案 5 :(得分:-2)

查看glob()函数的PHP手册:http://php.net/glob

在评论中有关于如何使其递归的例子。