Đếm bao nhiêu tệp trong thư mục PHP


106

Tôi đang thực hiện một dự án hơi mới. Tôi muốn biết có bao nhiêu tệp trong một thư mục nhất định.

<div id="header">
<?php 
    $dir = opendir('uploads/'); # This is the directory it will count from
    $i = 0; # Integer starts at 0 before counting

    # While false is not equal to the filedirectory
    while (false !== ($file = readdir($dir))) { 
        if (!in_array($file, array('.', '..') and !is_dir($file)) $i++;
    }

    echo "There were $i files"; # Prints out how many were in the directory
?>
</div>

Đây là những gì tôi có cho đến nay (từ việc tìm kiếm). Tuy nhiên, nó không xuất hiện đúng cách? Tôi đã thêm một số ghi chú nên hãy xóa chúng đi, chúng chỉ để tôi có thể hiểu nó tốt nhất có thể.

Nếu bạn cần thêm một số thông tin hoặc cảm thấy như thể tôi chưa mô tả điều này đủ, vui lòng nêu rõ.


4
Sẽ ngắn hơn nếu sử dụng một thành ngữ giống như count(scandir("uploads/")) - 2vòng lặp đó.
mario

@mario Cẩn thận! scandir là tốt đẹp, nhưng -2 là không chính xác là tốt nhất - bạn có thể được trong một thư mục gốc hoặc các thư mục có thể có các thư mục bên trong - Laurent Brieu có một tấm séc tốt đẹp cho ./ .. và thư mục :)
jave.web

Câu trả lời:


261

Bạn chỉ cần làm như sau:

$fi = new FilesystemIterator(__DIR__, FilesystemIterator::SKIP_DOTS);
printf("There were %d Files", iterator_count($fi));

22
+1 vì điều này rất dễ thương, nhưng tôi có thể tưởng tượng rằng nó khá khó hiểu / khó đọc đối với hầu hết các nhà phát triển PHP. Tôi sẽ đi với một trong những cách tiếp cận trong các câu trả lời khác.
user428517

Mặc dù hữu ích nhưng nó không dễ đọc khi tôi hỏi câu hỏi. Nói vậy nhưng tôi đã nâng cao kiến ​​thức về php. Tôi đã không ủng hộ điều này.
Bradly Spicer

2
Đây phải là câu trả lời được chấp nhận, trừ khi người hỏi muốn có phiên bản tùy chỉnh hơn, nơi họ có thể loại trừ một số tệp nhất định.
Abhishek Madhani

1
Do mọi người đang nói rằng điều này là khó hiểu đối với một số nhà phát triển, chúng tôi nên nói thêm rằng nếu một người đang sử dụng không gian tên (vì phương pháp này yêu cầu phiên bản PHP gần đây trong mọi trường hợp), thì người ta cũng phải chỉ định không gian tên: $ fi = new \ FilesystemIterator ( DIR , \ FilesystemIterator :: SKIP_DOTS);
graemeboy

2
Bạn không cần phải vượt qua cờ FilesystemIterator::SKIP_DOTSvì đó là mặc định.
Eborbob

70

Bạn có thể lấy số lượng tệp như sau:

$directory = "/path/to/dir/";
$filecount = 0;
$files = glob($directory . "*");
if ($files){
 $filecount = count($files);
}
echo "There were $filecount files";

ở đâu, "*"bạn có thể thay đổi nó thành một loại tệp cụ thể nếu bạn muốn "*.jpg"hoặc bạn có thể thực hiện nhiều loại tệp như sau:

glob($directory . "*.{jpg,png,gif}",GLOB_BRACE)

các GLOB_BRACEnở cờ {a, b, c} để trận đấu 'a', 'b', hoặc 'c'


3
Tuyệt vời, có rất nhiều khả năng với cách tiếp cận này để lọc các tệp cũng như đếm chúng :) Tạo một vòng lặp đơn giản và một số điều kiện sẽ rất tuyệt vời ... Nhưng làm thế nào bạn có thể bao gồm các thư mục khác trong thư mục đó, v.v. các tệp và loại trừ các thư mục khỏi số lượng?
The Bumpaster

1
@TheBumpaster xem câu hỏi / câu trả lời SO này về cách quét các thư mục con với
perf

2
Đối với những người mà giải pháp này không hoạt động, hãy thêm __DIR__ . trước "/path/to/dir/"( __DIR__ . "/path/to/dir/")
dnns

@dnns Trên thực tế, thêm bất cứ thứ gì vào /path/to/dirsẽ không thành công, bởi vì đầu tiên /có nghĩa là starting from root dir. Nếu có path/to/dir, thì có, __DIR__ . '/path/to/dir'sẽ hữu ích (trong trường hợp này, bạn phải sử dụng /sau__DIR__
Justinas 22/02/19

43

Thử cái này.

// Directory
$directory = "/dir";

// Returns array of files
$files = scandir($directory);

// Count number of files and store them to variable..
$num_files = count($files)-2;

Không tính dấu '.' và '..'.


5
Có thể $num_files = count($files) - 2;? Bởi vì .cũng như..
Havelock

Lưu ý rằng nó cũng sẽ tính hai cái sau: '.' và '..'
Laurent Brieu

7
để thoát khỏi sự ...thử điều này: $ file =array_diff( scandir("/dir"), array(".", "..") );
JKirchartz

2
array_slice(scandir($directory),2)
Spooky

42

Bạn nên có:

<div id="header">
<?php 
    // integer starts at 0 before counting
    $i = 0; 
    $dir = 'uploads/';
    if ($handle = opendir($dir)) {
        while (($file = readdir($handle)) !== false){
            if (!in_array($file, array('.', '..')) && !is_dir($dir.$file)) 
                $i++;
        }
    }
    // prints out how many were in the directory
    echo "There were $i files";
?>
</div>

nó là mã giống nhau và không làm việc: $ file = readdir ($ dh) sẽ là $ file = readdir ($ dir)
Marco Pace

2
Sẽ rất tuyệt (và hữu ích trước tất cả) nếu chỉ ra những điểm khác biệt / sai lầm mà OP đã mắc phải trong một văn bản tối giản.
Havelock

1
Này, cảm ơn vì điều này. Nó vẫn sẽ không xuất hiện đối với tôi tuy nhiên tôi cảm thấy điều đó có thể liên quan đến biểu định kiểu của tôi hoặc một cái gì đó dọc theo những dòng đó. Dù bằng cách nào, cảm ơn rất nhiều vì sự giúp đỡ của bạn. Chỉnh sửa: Đã sửa :) Cảm ơn rất nhiều!
Bradly Spicer

Đừng quên để đóng thư mục :)
jave.web

16

Câu trả lời tốt nhất theo ý kiến ​​của tôi:

$num = count(glob("/exact/path/to/files/" . "*"));
echo $num;
  • Nó không được tính. và ..
  • Nó là một lớp lót
  • Tôi tự hào về nó

Chỉ cần nhận ra rằng bạn có thể sử dụng "thư mục / *" nếu tài liệu PHP của bạn nằm trong cùng một thư mục!

Một lót nên có uy tín thưởng x2 ... thực sự làm cho nó x3
baron_bartek

1
Ý anh là gì? "Nó không được tính".
habibhassani

13

Vì tôi cũng cần cái này, tôi tò mò không biết lựa chọn thay thế nào là nhanh nhất.

Tôi thấy rằng - nếu tất cả những gì bạn muốn là số lượng tệp - giải pháp của Baba nhanh hơn rất nhiều so với những giải pháp khác. Tôi khá ngạc nhiên.

Tự mình thử nó xem:

<?php
define('MYDIR', '...');

foreach (array(1, 2, 3) as $i)
{
    $t = microtime(true);
    $count = run($i);
    echo "$i: $count (".(microtime(true) - $t)." s)\n";
}

function run ($n)
{
    $func = "countFiles$n";
    $x = 0;
    for ($f = 0; $f < 5000; $f++)
        $x = $func();
    return $x;
}

function countFiles1 ()
{
    $dir = opendir(MYDIR);
    $c = 0;
    while (($file = readdir($dir)) !== false)
        if (!in_array($file, array('.', '..')))
            $c++;
    closedir($dir);
    return $c;
}

function countFiles2 ()
{
    chdir(MYDIR);
    return count(glob("*"));
}

function countFiles3 () // Fastest method
{
    $f = new FilesystemIterator(MYDIR, FilesystemIterator::SKIP_DOTS);
    return iterator_count($f);
}
?>

Chạy thử nghiệm: (rõ ràng là glob()không tính tệp chấm)

1: 99 (0.4815571308136 s)
2: 98 (0.96104407310486 s)
3: 99 (0.26513481140137 s)

Cuối cùng cái nào nhanh hơn như bạn không đề cập đến kết quả?
Alex,

Tôi đã nói rằng giải pháp của Baba là nhanh nhất, nhưng tất nhiên tôi nên rõ ràng hơn về kết quả. Đã sửa ngay.
vbwx

12

Demo làm việc

<?php

$directory = "../images/team/harry/"; // dir location
if (glob($directory . "*.*") != false)
{
 $filecount = count(glob($directory . "*.*"));
 echo $filecount;
}
else
{
 echo 0;
}

?>

Tôi sẽ tránh gọi tên tiếng Anh () 2 lần nếu bạn có nhiều tập tin trong thư mục. Thay vào đó, tôi sẽ gán kết quả của hình cầu đầu tiên vào biến và sử dụng số lượng trên biến này.
Konrad Gałęzowski

5

Tôi sử dụng cái này:

count(glob("yourdir/*",GLOB_BRACE))

Đây là lần đầu tiên phù hợp với tôi, nhưng có vấn đề là nó không cung cấp cho bạn sự đảm bảo rằng tất cả các tệp được tính là hình ảnh.
Sterling Diaz

1
<?php echo(count(array_slice(scandir($directory),2))); ?>

array_slicehoạt động tương tự như substrchức năng, chỉ nó hoạt động với mảng.

Ví dụ: điều này sẽ cắt hai khóa mảng đầu tiên khỏi mảng:

$key_zero_one = array_slice($someArray, 0, 2);

Và nếu Bạn bỏ qua tham số đầu tiên, như trong ví dụ đầu tiên, mảng sẽ không chứa hai cặp khóa / giá trị đầu tiên * ('.' Và '..').


1
Về cơ bản đây là câu trả lời giống như đã được đề xuất bởi các áp phích khác. Bạn có thể cải thiện câu trả lời của mình hoặc thêm bất kỳ thông tin nào khác ngoài những gì đã được thảo luận không?
Joe Miller

Tốt hơn .. ? Hãy để họ đọc hướng dẫn sử dụng php.net nhiều hơn bình thường một chút. :)
Spooky

1

Có thể hữu ích cho ai đó. Trên hệ thống Windows, bạn có thể cho phép Windows thực hiện công việc bằng cách gọi lệnh dir. Tôi sử dụng một đường dẫn tuyệt đối, giống như E:/mydir/mysubdir.

<?php 
$mydir='E:/mydir/mysubdir';
$dir=str_replace('/','\\',$mydir);
$total = exec('dir '.$dir.' /b/a-d | find /v /c "::"');

0
$it = new filesystemiterator(dirname("Enter directory here"));
printf("There were %d Files", iterator_count($it));
echo("<br/>");
    foreach ($it as $fileinfo) {
        echo $fileinfo->getFilename() . "<br/>\n";
    } 

Điều này sẽ hoạt động, hãy nhập thư mục vào dirname. và để điều kỳ diệu xảy ra.


0
$files = glob('uploads/*');
$count = 0;
$totalCount = 0;
$subFileCount = 0;
foreach ($files as $file) 
{  
    global $count, $totalCount;
    if(is_dir($file))
    {
        $totalCount += getFileCount($file);
    }
    if(is_file($file))
    {
        $count++;  
    }  
}

function getFileCount($dir)
{
    global $subFileCount;
    if(is_dir($dir))
    {
        $subfiles = glob($dir.'/*');
        if(count($subfiles))
        {      
            foreach ($subfiles as $file) 
            {
                getFileCount($file);
            }
        }
    }
    if(is_file($dir))
    {
        $subFileCount++;
    }
    return $subFileCount;
}

$totalFilesCount = $count + $totalCount; 
echo 'Total Files Count ' . $totalFilesCount;

0

Dựa trên câu trả lời được chấp nhận, đây là một cách để đếm tất cả các tệp trong một thư mục NHẬN ĐƯỢC:

iterator_count(
    new \RecursiveIteratorIterator(
        new \RecursiveDirectoryIterator('/your/directory/here/', \FilesystemIterator::SKIP_DOTS)
    )
)

0

Đây là một chức năng PHP Linux nhanh đáng kể. Một chút bẩn, nhưng nó sẽ hoàn thành công việc!

$ dir - đường dẫn đến thư mục

$ type - f, d hoặc false (theo mặc định)

f - chỉ trả về số lượng tệp

d - chỉ trả về số thư mục

false - trả về tổng số tệp và thư mục

function folderfiles($dir, $type=false) {
    $f = escapeshellarg($dir);
    if($type == 'f') {
        $io = popen ( '/usr/bin/find ' . $f . ' -type f | wc -l', 'r' );
    } elseif($type == 'd') {
        $io = popen ( '/usr/bin/find ' . $f . ' -type d | wc -l', 'r' );
    } else {
        $io = popen ( '/usr/bin/find ' . $f . ' | wc -l', 'r' );
    }

    $size = fgets ( $io, 4096);
    pclose ( $io );
    return $size;
}

Bạn có thể điều chỉnh để phù hợp với nhu cầu của mình.

Xin lưu ý rằng điều này sẽ không hoạt động trên Windows.


-2
  simple code add for file .php then your folder which number of file to count its      

    $directory = "images/icons";
    $files = scandir($directory);
    for($i = 0 ; $i < count($files) ; $i++){
        if($files[$i] !='.' && $files[$i] !='..')
        { echo $files[$i]; echo "<br>";
            $file_new[] = $files[$i];
        }
    }
    echo $num_files = count($file_new);

đơn giản thêm vào là xong ....


thêm một số giải thích vào mã của bạn để làm cho nó rõ ràng hơn.
Alex.K.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.