Порахуйте, скільки файлів у каталогу 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.