Подсчитайте, сколько файлов в каталоге 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 Осторожно! scandir - это хорошо, но -2 не совсем лучший вариант - вы можете находиться в корневом каталоге или в каталоге могут быть каталоги внутри - у Лорана Брие есть хорошая проверка для ./ .. и каталогов :)
jave.web

Ответы:


263

Вы можете просто сделать следующее:

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

22
+1, потому что это мило, но я могу представить, что это довольно запутанное / нечитаемое для большинства разработчиков PHP. Я бы выбрал один из подходов в других ответах.
user428517

Когда я задал вопрос, его было нелегко прочитать. Сказав это, я улучшил свои знания php. Я не проголосовал за это.
Брэдли Спайсер

2
Это должен быть принятый ответ, если только спрашивающий не хочет более настроенную версию, в которой он может исключить определенные файлы.
Абхишек Мадхани

1
Учитывая, что люди говорят, что это сбивает с толку некоторых разработчиков, следует ли добавить, что если кто-то использует пространства имен (поскольку для этого метода в любом случае требуется последняя версия PHP), то необходимо также указать пространство имен: $ fi = new \ FilesystemIterator ( DIR , \ FilesystemIterator :: SKIP_DOTS);
graemeboy

2
В 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флаг расширяется {а, b, c} , чтобы соответствовать 'A', 'B', или 'с'


3
Замечательно, у этого подхода есть много возможностей для фильтрации файлов, а также их подсчета :) Было бы здорово создать простой цикл и несколько условий ... Но как вы можете включить другие каталоги в эти каталоги и так далее, чтобы подсчитать все файлы и исключить каталоги из подсчета?
The Bumpaster 02

1
@TheBumpaster ознакомьтесь с этим SO-вопросом / ответами о том, как сканировать подкаталоги с помощью glob: stackoverflow.com/q/12109042/276250
JKirchartz 02

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;? Из-за, .а также..
Хэвлок

Обратите внимание, что он также будет считать эти два: '.' и '..'
Лоран Бриё

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)
Марко Пейс

2
Было бы неплохо (и прежде всего полезно) указать на различия / ошибки, допущенные OP в минималистичном тексте.
Хэвлок,

1
Привет, спасибо за это. Он по-прежнему не отображается для меня, но я чувствую, что это может быть связано с моей таблицей стилей или чем-то в этом роде. В любом случае большое спасибо за вашу помощь. Изменить: Исправлено :) Большое спасибо!
Брэдли Спайсер,

Не забудьте закрыть каталог :)
jave.web

16

На мой взгляд, лучший ответ:

$num = count(glob("/exact/path/to/files/" . "*"));
echo $num;
  • Это не в счет. и ..
  • Это один лайнер
  • Я горжусь этим

Только что понял, что вы можете использовать "folder / *", если ваш PHP-документ находится в том же каталоге!

Один лайнер должен иметь награды за репутацию x2 ... на самом деле сделать это x3
baron_bartek

1
Что вы имеете в виду? «Это не в счет».
habibhassani

13

Поскольку мне это тоже было нужно, мне было любопытно, какая альтернатива была бы самой быстрой.

Я обнаружил, что - если все, что вам нужно - это количество файлов - решение Бабы намного быстрее, чем другие. Я был очень удивлен.

Попробуй сам:

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

Я сказал, что решение Бабы было самым быстрым, но, конечно, я должен был быть более ясным в отношении результатов. Исправлено сейчас.
vbwx

12

Рабочая демонстрация

<?php

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

?>

Я бы не стал вызывать glob () 2 раза, если у вас много файлов в каталоге. Вместо этого я бы назначил результат первого глобуса переменной и использовал счетчик для этой переменной.
Конрад Галензовски

5

Я использую это:

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

Это первый подход, который у меня работает, но проблема заключается в том, что он не дает уверенности в том, что все учитываемые файлы являются изображениями.
Стерлинг Диаз,

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

array_sliceработает аналогично substrфункции, только с массивами.

Например, это будет вырезать первые два ключа массива из массива:

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

И если вы опустите первый параметр, как в первом примере, массив не будет содержать первых двух пар ключ / значение * ('.' И '..').


1
По сути, это тот же ответ, который уже предлагали другие авторы. Можете ли вы улучшить свой ответ или добавить дополнительную информацию, кроме уже обсужденной?
Джо Миллер

Лучше .. ? Пусть читают руководство по 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

Основываясь на принятом ответе, вот способ РЕКУРСИВНО подсчитать все файлы в каталоге:

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

0

Вот довольно быстрая функция PHP Linux. Немного грязный, но он выполняет свою работу!

$ dir - путь к директории

$ type - f, d или false (по умолчанию)

f - возвращает только количество файлов

d - возвращает только количество папок

false - возвращает общее количество файлов и папок

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.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.