134

I'm working on a slightly new project. I wanted to know how many files are in a certain directory.

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

This is what I have so far (from searching). However, it is not appearing properly? I have added a few notes so feel free to remove them, they are just so I can understand it as best as I can.

If you require some more information or feel as if I haven't described this enough please feel free to state so.

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Bradly Spicer
  • 2,278
  • 5
  • 24
  • 34
  • 5
    It would be shorter to use an idiom like `count(scandir("uploads/")) - 2` than that loop. – mario Oct 09 '12 at 13:41
  • 1
    @mario **Careful!** *scandir* is nice, but -2 is not exactly the best - you can be in a root directory or the directory can have directories inside - **Laurent Brieu has a nice check for ./.. and directories** :) – jave.web Aug 21 '13 at 07:54

15 Answers15

307

You can simply do the following :

$fi = new FilesystemIterator(__DIR__, FilesystemIterator::SKIP_DOTS);
printf("There were %d Files", iterator_count($fi));
Baba
  • 94,024
  • 28
  • 166
  • 217
  • 7
    You don't need to pass in the flag `FilesystemIterator::SKIP_DOTS` as that's default anyway. – Eborbob Feb 22 '18 at 15:45
  • Is it possible to look for specific filetypes with FilesystemIterator? It looks not possible with the docs, but I may be misreading something important. Otherwise something like [this answer](https://stackoverflow.com/questions/42264823/how-to-count-number-of-txt-files-in-a-directory-in-php) would do – a coder Jan 19 '23 at 20:52
93

You can get the filecount like so:

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

where the "*" is you can change that to a specific filetype if you want like "*.jpg" or you could do multiple filetypes like this:

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

the GLOB_BRACE flag expands {a,b,c} to match 'a', 'b', or 'c'

Note that glob() skips Linux hidden files, or all files whose names are starting from a dot, i.e. .htaccess.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
JKirchartz
  • 17,612
  • 7
  • 60
  • 88
  • 3
    Awesome, there are a lot of possibilities with this approach to filter files as well as count them :) Creating a simple loop and several conditions would be great... But how can you include other directories within that directories and so on to count all files and exclude directories from the count? – The Bumpaster Jul 02 '16 at 13:40
  • 1
    @TheBumpaster check out this SO question/answers on how to scan subdirectories with glob: http://stackoverflow.com/q/12109042/276250 – JKirchartz Jul 02 '16 at 15:48
  • 2
    For whom this solution doesn't work, add `__DIR__ . ` before `"/path/to/dir/"` (`__DIR__ . "/path/to/dir/"`) – dnns Sep 28 '18 at 16:10
  • @dnns Actually adding anything to `/path/to/dir` would fail it, because first `/` means `starting from root dir`. If there were `path/to/dir`, then yes, `__DIR__ . '/path/to/dir'` would help (in this case you must use `/` after `__DIR__` – Justinas Feb 22 '19 at 14:30
57

Try this.

// Directory
$directory = "/dir";

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

// Count the number of files and store them inside the variable..
// Removing 2 because we do not count '.' and '..'.
$num_files = count($files)-2;
Shlomi Hassid
  • 6,500
  • 3
  • 27
  • 48
intelis
  • 7,829
  • 14
  • 58
  • 102
44

You should have :

<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>
Laurent Brieu
  • 3,331
  • 1
  • 14
  • 15
  • it is the same code and doesn't work: $file = readdir($dh) should be $file = readdir($dir) – Marco Pace Oct 09 '12 at 13:45
  • 4
    It would be nice (and helpfull before all) to point out the differences / mistakes the OP has made in a minimalistic text. – Havelock Oct 09 '12 at 13:45
  • 2
    Hey there, thanks for this. It still won't appear for me however I feel that might be to do with my stylesheet or something along those lines. Either way thanks very much for your help. Edit: Fixed :) Thanks very much! – Bradly Spicer Oct 09 '12 at 13:52
  • 2
    Dont forget to close the directory :) – jave.web Aug 21 '13 at 08:06
40

The best answer in my opinion:

$num = count(glob("/exact/path/to/files/" . "*"));
echo $num;
  • It doesnt counts . and ..
  • Its a one liner
  • Im proud of it
16

Since I needed this too, I was curious as to which alternative was the fastest.

I found that -- if all you want is a file count -- Baba's solution is a lot faster than the others. I was quite surprised.

Try it out for yourself:

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

Test run: (obviously, glob() doesn't count dot-files)

1: 99 (0.4815571308136 s)
2: 98 (0.96104407310486 s)
3: 99 (0.26513481140137 s)
vbwx
  • 388
  • 6
  • 12
  • 1
    Finally which one is faster as you didn't mentioned result? – Alex Nov 07 '14 at 11:04
  • 1
    I did say that Baba's solution was fastest, but of course I should've been clearer about the results. Fixed now. – vbwx Dec 12 '14 at 21:09
12

Working Demo

<?php

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

?>
Nirav Ranpara
  • 13,753
  • 3
  • 39
  • 54
  • I would avoid calling glob() 2 times if you have lots of files in directory. Instead I would assign result of first glob into variable and use count on this variable. – Konrad Gałęzowski Feb 22 '17 at 17:58
7

I use this:

count(glob("yourdir/*",GLOB_BRACE))
Philipp Werminghausen
  • 1,142
  • 11
  • 29
  • This is the first that works for me, but has the problem that it does not gives you assurance that all files counted are images. – Sterling Diaz Apr 19 '14 at 19:27
3
<?php echo(count(array_slice(scandir($directory),2))); ?>

array_slice works similary like substr function, only it works with arrays.

For example, this would chop out first two array keys from array:

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

And if You ommit the first parameter, like in first example, array will not contain first two key/value pairs *('.' and '..').

Spooky
  • 1,235
  • 15
  • 17
  • 1
    This is basically the same answer as has already been proposed by other posters. Can you improve on your answer, or add any more information other than has already been discussed? – Joe Miller Apr 09 '16 at 22:29
  • Better .. ? Let them read php.net manual a little bit more than usual. :) – Spooky Apr 10 '16 at 07:38
3

Based on the accepted answer, here is a way to count all files in a directory RECURSIVELY:

iterator_count(
    new \RecursiveIteratorIterator(
        new \RecursiveDirectoryIterator('/your/directory/here/', \FilesystemIterator::SKIP_DOTS)
    )
)
Panni
  • 310
  • 4
  • 14
1
$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";
    } 

This should work enter the directory in dirname. and let the magic happen.

oussama
  • 11
  • 1
1

Maybe usefull to someone. On a Windows system, you can let Windows do the job by calling the dir-command. I use an absolute path, like E:/mydir/mysubdir.

<?php 
$mydir='E:/mydir/mysubdir';
$dir=str_replace('/','\\',$mydir);
$total = exec('dir '.$dir.' /b/a-d | find /v /c "::"');
Michel
  • 4,076
  • 4
  • 34
  • 52
1
$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;
1

Here's a PHP Linux function that's considerably fast. A bit dirty, but it gets the job done!

$dir - path to directory

$type - f, d or false (by default)

f - returns only files count

d - returns only folders count

false - returns total files and folders count

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

You can tweak to fit your needs.

Please note that this will not work on Windows.

GTodorov
  • 1,993
  • 21
  • 24
-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);

simple add its done ....

parajs dfsb
  • 145
  • 2
  • 4
  • 13