นับจำนวนไฟล์ในไดเรกทอรี PHP


108

ฉันกำลังทำโปรเจ็กต์ใหม่เล็กน้อย ฉันอยากรู้ว่ามีกี่ไฟล์ในไดเร็กทอรีหนึ่ง

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

นี่คือสิ่งที่ฉันมีจนถึงตอนนี้ (จากการค้นหา) อย่างไรก็ตามมันไม่ปรากฏอย่างถูกต้อง? ฉันได้เพิ่มโน้ตสองสามโน้ตดังนั้นอย่าลังเลที่จะลบออก แต่เพียงเพื่อให้ฉันสามารถเข้าใจได้ดีที่สุดเท่าที่จะทำได้

หากคุณต้องการข้อมูลเพิ่มเติมหรือรู้สึกราวกับว่าฉันไม่ได้อธิบายสิ่งนี้เพียงพอโปรดอย่าลังเลที่จะระบุ


4
มันจะสั้นกว่าที่จะใช้สำนวนเหมือนcount(scandir("uploads/")) - 2ลูปนั้น
มาริโอ

@mario ระวัง! เรื่องอื้อฉาวเป็นสิ่งที่ดี แต่ -2 ไม่ได้ดีที่สุด - คุณสามารถอยู่ในไดเรกทอรีรากหรือไดเรกทอรีสามารถมีไดเรกทอรีภายในได้ - Laurent Brieu มีการตรวจสอบที่ดีสำหรับ. / .. และไดเรกทอรี :)
jave.web

คำตอบ:


264

คุณสามารถทำสิ่งต่อไปนี้:

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

22
+1 เพราะมันน่ารัก แต่ฉันสามารถจินตนาการได้ว่ามันค่อนข้างสับสน / อ่านไม่ออกสำหรับนักพัฒนา PHP ส่วนใหญ่ ฉันจะใช้วิธีใดวิธีหนึ่งในคำตอบอื่น ๆ
user428517

แม้ว่าจะมีประโยชน์ แต่ก็ไม่ง่ายที่จะอ่านเมื่อฉันถามคำถาม พูดอย่างนั้นฉันได้พัฒนาความรู้เกี่ยวกับ php ฉันไม่ได้เพิ่มคะแนนนี้
Bradly Spicer

2
นี่ควรเป็นคำตอบที่ได้รับการยอมรับเว้นแต่ผู้ถามต้องการเวอร์ชันที่ปรับแต่งเพิ่มเติมซึ่งพวกเขาสามารถยกเว้นไฟล์บางไฟล์ได้
Abhishek Madhani

1
เนื่องจากผู้คนพูดว่าสิ่งนี้สร้างความสับสนให้กับนักพัฒนาบางคนเราควรเพิ่มว่าหากมีคนใช้เนมสเปซ (เนื่องจากวิธีนี้ต้องใช้ PHP เวอร์ชันล่าสุดไม่ว่าในกรณีใด ๆ ) จึงต้องระบุเนมสเปซด้วย: $ fi = new \ FilesystemIterator ( DIR , \ FilesystemIterator :: SKIP_DOTS);
graemeboy

3
คุณไม่จำเป็นต้องส่งต่อในแฟล็กFilesystemIterator::SKIP_DOTSเนื่องจากเป็นค่าเริ่มต้นอยู่แล้ว
Eborbob

70

คุณจะได้รับจำนวนไฟล์ดังนี้:

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

"*"คุณสามารถเปลี่ยนเป็นประเภทไฟล์เฉพาะได้ที่ไหนถ้าคุณต้องการเช่น"*.jpg"หรือคุณสามารถทำหลายประเภทไฟล์เช่นนี้:

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

GLOB_BRACEขยายธง {A, B, C} จะมีการแข่งขัน 'a', 'B' หรือ 'C'


3
ยอดเยี่ยมมีความเป็นไปได้มากมายสำหรับวิธีนี้ในการกรองไฟล์และนับไฟล์ :) การสร้างลูปง่ายๆและเงื่อนไขหลาย ๆ อย่างจะดีมาก ... แต่คุณจะรวมไดเรกทอรีอื่น ๆ ไว้ในไดเรกทอรีนั้นได้อย่างไรและจะนับทั้งหมดได้อย่างไร ไฟล์และไม่รวมไดเรกทอรีจากการนับ?
The Bumpaster

1
@TheBumpaster ตรวจสอบคำถาม / คำตอบ SO นี้เกี่ยวกับวิธีการสแกนไดเรกทอรีย่อยด้วย glob: stackoverflow.com/q/12109042/276250
JKirchartz

2
สำหรับใครที่วิธีนี้ใช้ไม่ได้ผลให้เพิ่ม__DIR__ . before "/path/to/dir/"( __DIR__ . "/path/to/dir/")
dnns

@dnns จริงๆแล้วการเพิ่มอะไรเข้าไป/path/to/dirก็จะล้มเหลวเพราะ/หมายถึงstarting from root dirประการแรก ถ้ามีpath/to/dirก็__DIR__ . '/path/to/dir'จะช่วยได้ (ในกรณีนี้คุณต้องใช้/หลังจาก__DIR__
Justinas

43

ลองทำตามนี้

// Directory
$directory = "/dir";

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

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

ไม่นับ "." และ '.. '.


5
อาจจะ$num_files = count($files) - 2;? เนื่องจาก.เช่นเดียวกับ..
Havelock

โปรดทราบว่าจะนับสองสิ่งนี้ด้วย: '.' และ '.. '
Laurent Brieu

7
เพื่อกำจัด.และ..ลองสิ่งนี้: $ files =array_diff( scandir("/dir"), array(".", "..") );
JKirchartz

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

42

คุณควรจะมี :

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

เป็นรหัสเดียวกันและใช้ไม่ได้: $ file = readdir ($ dh) ควรเป็น $ file = readdir ($ dir)
Marco Pace

2
มันจะดี (และเป็นประโยชน์ก่อนทั้งหมด) ที่จะชี้ให้เห็นความแตกต่าง / ข้อผิดพลาดที่ OP ทำในข้อความที่เรียบง่าย
Havelock

1
สวัสดีขอบคุณสำหรับสิ่งนี้ มันยังไม่ปรากฏให้ฉันเห็น แต่ฉันรู้สึกว่าอาจจะเกี่ยวกับสไตล์ชีตของฉันหรืออะไรบางอย่างตามบรรทัดเหล่านั้น ไม่ว่าจะด้วยวิธีใดขอบคุณมากสำหรับความช่วยเหลือของคุณ แก้ไข: แก้ไข :) ขอบคุณมาก!
Bradly Spicer

อย่าลืมปิดไดเร็กทอรี :)
jave.web

16

คำตอบที่ดีที่สุดในความคิดของฉัน:

$num = count(glob("/exact/path/to/files/" . "*"));
echo $num;
  • มันไม่นับ และ ..
  • เป็นซับเดียว
  • ฉันภูมิใจกับมัน

เพิ่งรู้ว่าคุณสามารถใช้ "โฟลเดอร์ / *" ได้หากเอกสาร PHP ของคุณอยู่ในไดเรกทอรีเดียวกัน!

หนึ่งสมุทรควรได้รับรางวัลชื่อเสียง x2 ... ทำให้ได้ x3
baron_bartek

1
คุณหมายถึงอะไร? "มันไม่นับ".
habibhassani

หมายความว่าจะไม่นับจุด / จุด ( .หรือ..) ที่แสดงถึงไดเร็กทอรีปัจจุบันและพาเรนต์
Ben Croker

14

เนื่องจากฉันต้องการสิ่งนี้เช่นกันฉันจึงอยากรู้ว่าทางเลือกใดที่เร็วที่สุด

ฉันพบว่า - ถ้าทั้งหมดที่คุณต้องการคือการนับไฟล์ - วิธีการแก้ปัญหาของบาบาเป็นจำนวนมากได้เร็วกว่าคนอื่น ๆ ฉันค่อนข้างประหลาดใจ

ลองด้วยตัวคุณเอง:

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

ทดสอบการทำงาน: (เห็นได้ชัดว่าglob()ไม่นับไฟล์ดอท)

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

สุดท้ายอันไหนเร็วกว่าที่คุณไม่ได้กล่าวถึงผลลัพธ์
Alex

ฉันบอกว่าวิธีแก้ปัญหาของ Baba นั้นเร็วที่สุด แต่แน่นอนว่าฉันควรจะชัดเจนกว่านี้เกี่ยวกับผลลัพธ์ แก้ไขแล้ว
vbwx

12

การสาธิตการทำงาน

<?php

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

?>

ฉันจะหลีกเลี่ยงการเรียก glob () 2 ครั้งหากคุณมีไฟล์จำนวนมากในไดเรกทอรี แต่ฉันจะกำหนดผลลัพธ์ของ glob แรกเป็นตัวแปรและใช้การนับตัวแปรนี้
Konrad Gałęzowski

5

ฉันใช้สิ่งนี้:

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

นี่เป็นครั้งแรกที่ใช้ได้สำหรับฉัน แต่มีปัญหาว่ามันไม่ได้ทำให้คุณมั่นใจได้ว่าไฟล์ทั้งหมดที่นับเป็นภาพ
Sterling Diaz

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

array_sliceใช้งานได้คล้ายกับsubstrฟังก์ชัน แต่ใช้ได้กับอาร์เรย์เท่านั้น

ตัวอย่างเช่นสิ่งนี้จะตัดคีย์อาร์เรย์สองคีย์แรกออกจากอาร์เรย์:

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

และถ้าคุณเลือกพารามิเตอร์ตัวแรกเช่นในตัวอย่างแรกอาร์เรย์จะไม่มีคู่คีย์ / ค่าสองคู่แรก * ('.' และ '.. ')


1
นี่เป็นคำตอบเดียวกับที่ผู้โพสต์คนอื่นเสนอไปแล้ว คุณสามารถปรับปรุงคำตอบของคุณหรือเพิ่มข้อมูลอื่น ๆ นอกเหนือจากที่ได้กล่าวไปแล้วได้หรือไม่?
Joe Miller

ดีกว่า .. ? ให้พวกเขาอ่านคู่มือ php.net ให้มากขึ้นกว่าปกติ :)
Spooky

1

อาจเป็นประโยชน์กับใครบางคน ในระบบ Windows คุณสามารถปล่อยให้ Windows ทำงานได้โดยเรียกคำสั่ง dir ฉันใช้เส้นทางที่แน่นอนเช่น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";
    } 

สิ่งนี้ควรทำงานเข้าสู่ไดเรกทอรีใน dirname และปล่อยให้เวทมนตร์เกิดขึ้น


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

จากคำตอบที่ยอมรับนี่คือวิธีการนับไฟล์ทั้งหมดในไดเร็กทอรี RECURSIVELY:

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

0

นี่คือฟังก์ชัน PHP Linux ที่เร็วมาก สกปรกไปหน่อย แต่งานเสร็จ!

$ dir - พา ธ ไปยังไดเร็กทอรี

$ type - f, d หรือ false (โดยค่าเริ่มต้น)

f - ส่งคืนเฉพาะไฟล์ที่นับ

d - คืนค่าเฉพาะโฟลเดอร์เท่านั้น

เท็จ - ส่งคืนจำนวนไฟล์และโฟลเดอร์ทั้งหมด

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

คุณสามารถปรับแต่งให้เหมาะกับความต้องการของคุณ

โปรดทราบว่าสิ่งนี้จะไม่ทำงานบน 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);

ง่าย ๆ เพิ่มเสร็จ ....


เพิ่มคำอธิบายลงในโค้ดของคุณเพื่อให้ชัดเจนขึ้น
Alex.K.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.