Порахуйте, скільки файлів у каталогу PHP


107

Я працюю над трохи новим проектом. Мені хотілося знати, скільки файлів у певному каталозі.

<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

@mario Обережно! scandir - це приємно, але -2 - не зовсім найкраще - ти можеш знаходитись у кореневій директорії або у каталозі, якщо всередині цього каталогу є каталоги - Лоран Бріє добре перевірив ./ .. та каталоги :)
— jave.web

Відповіді:


262

Ви можете просто зробити наступне:

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

22
+1, тому що це мило, але я можу уявити, що він досить заплутаний / нечитабельний для більшості розробників PHP. Я б пішов з одним із підходів в інших відповідях.
— user428517

Хоча корисно, прочитати це питання було не дуже просто. Сказавши це, я вдосконалив свої знання з php. Я цього не підтримав.
— Bradly Spicer

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
Дивовижно, існує багато можливостей при такому підході до фільтрування файлів, а також до їх підрахунку :) Створення простого циклу та декількох умов було б чудово ... Але як ви можете включити інші каталоги в ці каталоги і так далі порахувати всі файли та виключити каталоги з рахунку?
— Bumpaster

1
@TheBumpaster перевірити це так питання / відповідь про те , як сканування підкаталогів з Glob: stackoverflow.com/q/12109042/276250
— JKirchartz

2
Для кого це рішення не працює, додайте __DIR__ . до "/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

Зауважте, що він також буде рахувати ці два: '.' і '..'
— Лоран Бріо

7
щоб позбутися .і ..спробувати це: $ files =array_diff( scandir("/dir"), array(".", "..") );
— JKirchartz

2
array_slice(scandir($directory),2)
— Моторошний

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
Було б добре (і корисно, перш за все) вказати на відмінності / помилки, допущені ОП у мінімалістичному тексті.
— Хавелок

1
Гей, дякую за це. Він все ще не з’явиться для мене, проте я вважаю, що це може стосуватися моєї таблиці стилів чи чогось у цьому напрямку. У будь-якому випадку дуже дякую за вашу допомогу. Редагувати: Виправлено :) Дуже дякую!
— Bradly Spicer

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

16

Найкраща відповідь на мій погляд:

$num = count(glob("/exact/path/to/files/" . "*"));
echo $num;
  • Це не рахується. і ..
  • Це один вкладиш
  • Я пишаюся цим

Щойно зрозумів, що ви можете використовувати "папку / *", якщо ваш 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)

Нарешті, який із них швидше, як ви не згадали результат?
— Олексій

Я сказав, що рішення Баби було найшвидшим, але, звичайно, я повинен був бути більш зрозумілим щодо результатів. Виправлено зараз.
— vbwx

12

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

<?php

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

?>

Я б уникав дзвонити glob () 2 рази, якщо у вас багато файлів у каталозі. Натомість я призначив би результат першого глобу в змінну і використав би рахунок на цю змінну.
— Konrad Gałęzowski


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

просто додати зроблено ....


додайте до свого коду пояснення, щоб зробити його зрозумілішим.
— Алекс.К.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.