2009-03-12 17 views
7

Einfache Frage für ein Newb und mein Google-Fu ist fehlgeschlagen. Wie können Sie mit PHP die Anzahl der Dateien in einem bestimmten Verzeichnis zählen, einschließlich aller Unterverzeichnisse (und eventuell vorhandener Unterverzeichnisse usw.)? z.B. wenn Verzeichnisstruktur wie folgt aussieht:Rekursiv zählende Dateien mit 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 

Das Skript sollte mit ‚5‘ Rückkehr für „./Dir_A“.

Ich habe zusammen die gepflasterten folgend, aber es ist nicht ganz die richtige Antwort zurückkehren, und ich bin nicht sicher, warum:

 
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; }

ich sehr jede mögliche Hilfe schätzen würde.

Antwort

15

Dies sollte den Trick:

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; 
} 
+0

Dieser Code funktioniert genau wie gewünscht. –

+0

Hallo. Danke für die schnelle Hilfe. Dieses Skript führt zu einem Zeitüberschreitungsfehler für mich. "Fataler Fehler: Maximale Ausführungszeit von 30 Sekunden überschritten". Nicht sicher warum. Im Zielverzeichnis befinden sich nur 8 Ordner und 68 Dateien. – user18359

+0

Versuchen Sie, die Kopie zu kopieren, die gerade dort ist. Meine ursprüngliche Antwort hatte einen Fehler, dieser ist getestet und funktioniert. –

0

Warum übergeben Sie $ filecount? Der [pass-in] Wert wird nicht verwendet; Die einzige Verwendung ist bei "$ total + = $ filecount" und Sie überschreiben $ filecount kurz davor.

Sie verpassen den Fall, wenn die Funktion auf eine normale (nicht dir) Datei trifft.

Edit: Ich habe gerade den Aufruf von glob() bemerkt. Es ist nicht nötig. Ihre Funktion berührt rekursiv jede Datei in der gesamten Verzeichnisstruktur. Siehe @Paolo Bergantinos Antwort.

13

Verwenden Sie die SPL, dann sehen, wenn Sie noch einen Fehler.

RecursiveDirectoryIterator

Anwendungsbeispiel:

<?php 

$path = realpath('/etc'); 

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

?> 

Dieser druckt eine Liste aller Dateien und Verzeichnisse unter $ Pfad (einschließlich $ path Blattes selber). Wenn Sie Verzeichnisse auslassen möchten, entfernen Sie den RecursiveIteratorIterator :: SELF_FIRST-Teil.

Dann einfach isDir verwenden()

+0

Dies tat auch den Trick, nachdem ich es für die $ ignore-Array geändert. Danke! – user18359

+0

benutze iterator_count ($ objects), um die Anzahl und Leistungen zu erhalten. – davidmars

-1

Überprüfen Sie die PHP-Handbuch auf glob() Funktion: http://php.net/glob

Es hat Beispiele in den Kommentaren, wie es rekursiv zu machen.

0

Paolo Bergantino war fast mit seinem Code, aber die Funktion wird immer noch .DS_Store Dateien zählen, da er es falsch geschrieben hat. Correct-Code unten

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; 
} 
0

basierend auf Andrew Antwort ...

$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! 

wie das ich in der Lage bin zu zählen (nicht kotiert) Tausende & Tausende Dateien. 680.642 Dateien in weniger als 4.6 Sekunden tatsächlich;)

Verwandte Themen