2009-03-12 44 views
7

Câu hỏi đơn giản về newb và Google-Fu của tôi không làm tôi thất vọng. Sử dụng PHP, làm thế nào bạn có thể đếm số lượng tệp trong một thư mục nhất định, bao gồm bất kỳ thư mục con nào (và bất kỳ thư mục con nào mà chúng có thể có, v.v.)? ví dụ. nếu cấu trúc thư mục trông giống như sau:Đệ quy đếm các tệp bằng 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 

Tập lệnh phải trả về bằng '5' cho "./Dir_A".

tôi đã gom góp sau nhưng nó không hoàn toàn quay trở lại câu trả lời đúng, và tôi không chắc chắn lý do tại sao:

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

tôi đánh giá rất cao sự giúp đỡ nào.

Trả lời

15

này nên làm như lừa:

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

Mã này hoạt động chính xác theo yêu cầu. –

+0

Xin chào. Cảm ơn sự hỗ trợ nhanh chóng. Kịch bản này gây ra lỗi hết thời gian chờ cho tôi. "Lỗi nghiêm trọng: Đã vượt quá thời gian thực hiện tối đa 30 giây". Không chắc chắn lý do tại sao. Chỉ có 8 thư mục và 68 tệp trong thư mục đích. – user18359

+0

Thử sao chép lại ảnh dán hiện đang có ở đó. Câu trả lời ban đầu của tôi có lỗi trong đó, câu trả lời này được kiểm tra và hoạt động. –

0

Tại sao bạn chuyển $ filecount? Giá trị [đã chuyển] không được sử dụng; cách sử dụng duy nhất là "$ total + = $ filecount" và bạn đang ghi đè $ filecount ngay trước đó.

Bạn đang thiếu trường hợp khi hàm gặp tệp thông thường (không phải dir).

Chỉnh sửa: Tôi vừa nhận thấy cuộc gọi tới glob(). Nó không cần thiết. Chức năng của bạn là đệ quy chạm vào mọi tập tin trong toàn bộ cây thư mục, dù sao đi nữa. Xem câu trả lời của @Paolo Bergantino.

13

Sử dụng SPL, sau đó xem nếu bạn vẫn nhận được một lỗi.

RecursiveDirectoryIterator

dụ Cách sử dụng:

<?php 

$path = realpath('/etc'); 

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

?> 

này in một danh sách tất cả các file và thư mục dưới $ đường dẫn (bao gồm $ path ifself). Nếu bạn muốn bỏ qua các thư mục, hãy xóa phần RecursiveIteratorIterator :: SELF_FIRST.

Sau đó, chỉ cần sử dụng isDir()

+0

Điều này cũng đã làm các trick sau khi tôi sửa đổi nó cho mảng $ ignore. – user18359

+0

sử dụng iterator_count ($ đối tượng) để nhận số lượng và hiệu suất. – davidmars

-1

Kiểm tra hướng dẫn PHP trên glob() chức năng: http://php.net/glob

Nó có ví dụ trong ý kiến ​​như thế nào để làm cho nó đệ quy.

0

Paolo Bergantino gần như đã có mã của anh ấy, nhưng chức năng vẫn sẽ tính .DS_Store tệp kể từ khi anh ấy viết sai chính tả. Mã đúng dưới đây

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

dựa trên câu trả lời của Andrew ...

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

như thế tôi có thể đếm được (không niêm yết) hàng ngàn & hàng ngàn tập tin. 680,642 tệp trong vòng chưa đầy 4,6 giây thực sự;)

Các vấn đề liên quan