Policz ile plików w katalogu PHP

108

Pracuję nad nieco nowym projektem. Chciałem wiedzieć, ile plików znajduje się w określonym katalogu.

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

To jest to, co mam do tej pory (od poszukiwań). Jednak nie wyświetla się prawidłowo? Dodałem kilka notatek, więc nie krępuj się, aby je usunąć, są po to, bym mógł je jak najlepiej zrozumieć.

Jeśli potrzebujesz więcej informacji lub czujesz, że nie opisałem tego wystarczająco wystarczająco, możesz to zaznaczyć.

Bradly Spicer
źródło
4
Użycie idiomu takiego count(scandir("uploads/")) - 2jak ta pętla byłoby krótsze .
mario
@mario Ostrożnie! scandir jest fajny, ale -2 nie jest do końca najlepsze - możesz być w katalogu głównym lub katalog może zawierać katalogi w środku - Laurent Brieu ma niezły test dla ./ .. i katalogów :)
jave.web

Odpowiedzi:

263

Możesz po prostu wykonać następujące czynności:

$fi = new FilesystemIterator(__DIR__, FilesystemIterator::SKIP_DOTS);
printf("There were %d Files", iterator_count($fi));
Baba
źródło
22
+1, ponieważ jest ładny, ale mogę sobie wyobrazić, że jest dość zagmatwany / nieczytelny dla większości programistów PHP. W pozostałych odpowiedziach wybrałbym jedno z podejść.
user428517
Chociaż było przydatne, nie było łatwo je przeczytać, kiedy zadałem pytanie. Mówiąc to jednak, poprawiłem swoją wiedzę o php. Nie głosowałem za tym.
Bradly Spicer
2
Powinna to być akceptowana odpowiedź, chyba że pytający chce bardziej dostosowanej wersji, w której mógłby wykluczyć określone pliki.
Abhishek Madhani
1
Biorąc pod uwagę, że ludzie mówią, że jest to mylące dla niektórych programistów, powinniśmy dodać, że jeśli ktoś używa przestrzeni nazw (ponieważ ta metoda w każdym przypadku wymaga najnowszej wersji PHP), należy również określić przestrzeń nazw: $ fi = new \ FilesystemIterator ( DIR , \ FilesystemIterator :: SKIP_DOTS);
graemeboy
2
Nie musisz przekazywać flagi, FilesystemIterator::SKIP_DOTSponieważ i tak jest to ustawienie domyślne.
Eborbob
70

Możesz pobrać liczbę plików w następujący sposób:

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

gdzie "*"jest, możesz zmienić to na określony typ pliku, jeśli chcesz, "*.jpg"lub możesz zrobić wiele typów plików, takich jak ten:

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

że GLOB_BRACErozszerza flag {a, b, c} pasujące do 'a', 'b', 'c' lub

JKirchartz
źródło
3
Super, jest wiele możliwości z tym podejściem do filtrowania plików, a także ich liczenia :) Stworzenie prostej pętli i kilku warunków byłoby świetne ... Ale jak możesz dołączyć inne katalogi do tych katalogów i tak dalej, aby policzyć wszystkie pliki i wykluczyć katalogi z liczenia?
The Bumpaster
1
@TheBumpaster sprawdź to pytanie / odpowiedzi SO dotyczące skanowania podkatalogów za pomocą glob: stackoverflow.com/q/12109042/276250
JKirchartz
2
Dla kogo to rozwiązanie nie działa, dodaj __DIR__ . przed "/path/to/dir/"( __DIR__ . "/path/to/dir/")
dnns
@dnns Właściwie dodanie czegokolwiek do /path/to/dirby nie powiodło się, ponieważ pierwsze /oznacza starting from root dir. Gdyby tak było path/to/dir, to tak, __DIR__ . '/path/to/dir'pomogłoby (w tym przypadku musisz użyć /po__DIR__
Justinas,
43

Spróbuj tego.

// Directory
$directory = "/dir";

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

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

Nie licząc „.” i '..'.

intelis
źródło
5
Może $num_files = count($files) - 2;? Z powodu, .jak również..
Havelock
Zauważ, że policzy również te dwa: '.' i „..”
Laurent Brieu
7
pozbyć się .i ..spróbować tego: $ files =array_diff( scandir("/dir"), array(".", "..") );
JKirchartz
2
array_slice(scandir($directory),2)
Spooky
42

Powinieneś mieć :

<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
źródło
to jest ten sam kod i nie działa: $ file = readdir ($ dh) powinno być $ file = readdir ($ dir)
Marco Pace
2
Byłoby miło (i przede wszystkim pomocne) wskazanie różnic / błędów popełnionych przez OP w minimalistycznym tekście.
Havelock
1
Hej, dzięki za to. Nadal się nie pojawi, ale wydaje mi się, że może to mieć związek z moim arkuszem stylów lub czymś podobnym. W każdym razie bardzo dziękuję za pomoc. Edycja: Naprawiono :) Bardzo dziękuję!
Bradly Spicer
Nie zapomnij zamknąć katalogu :)
jave.web
16

Najlepsza odpowiedź moim zdaniem:

$num = count(glob("/exact/path/to/files/" . "*"));
echo $num;
  • To się nie liczy. i ..
  • To jedna wkładka
  • Jestem z tego dumny

źródło
Właśnie sobie uświadomiłem, że możesz użyć "folder / *", jeśli twój dokument PHP znajduje się w tym samym katalogu!
Jeden liniowiec powinien mieć nagrody za reputację x2 ... a właściwie zrobić to x3
baron_bartek
1
Co masz na myśli? „To się nie liczy”.
habibhassani
13

Ponieważ ja też tego potrzebowałem, byłem ciekawy, która alternatywa jest najszybsza.

Odkryłem, że - jeśli chcesz tylko liczyć pliki - rozwiązanie Baby jest znacznie szybsze niż inne. Byłem dość zaskoczony.

Wypróbuj sam:

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

Uruchomienie testowe: (oczywiście glob()nie liczy plików z kropkami)

1: 99 (0.4815571308136 s)
2: 98 (0.96104407310486 s)
3: 99 (0.26513481140137 s)
vbwx
źródło
Wreszcie, który jest szybszy, ponieważ nie wspomniałeś o wyniku?
Alex
Powiedziałem, że rozwiązanie Baby było najszybsze, ale oczywiście powinienem był wyjaśnić wyniki. Naprawiono teraz.
vbwx
12

Działające demo

<?php

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

?>
Nirav Ranpara
źródło
Unikałbym wywoływania glob () 2 razy, jeśli masz dużo plików w katalogu. Zamiast tego przypiszę wynik pierwszej globu do zmiennej i użyję licznika na tej zmiennej.
Konrad Gałęzowski
5

Używam tego:

count(glob("yourdir/*",GLOB_BRACE))
Philipp Werminghausen
źródło
To jest pierwszy, który działa dla mnie, ale ma ten problem, że nie daje ci pewności, że wszystkie zliczane pliki to obrazy.
Sterling Diaz
1
<?php echo(count(array_slice(scandir($directory),2))); ?>

array_slicedziała podobnie jak substrfunkcja, tylko działa z tablicami.

Na przykład wydzieliłoby to pierwsze dwa klucze tablicy z tablicy:

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

A jeśli pominiesz pierwszy parametr, jak w pierwszym przykładzie, tablica nie będzie zawierać pierwszych dwóch par klucz / wartość * („.” I „..”).

Straszny
źródło
1
Jest to w zasadzie ta sama odpowiedź, która została już zaproponowana przez inne plakaty. Czy możesz poprawić swoją odpowiedź lub dodać więcej informacji innych niż już omówione?
Joe Miller
Lepszy .. ? Pozwól im przeczytać podręcznik php.net trochę więcej niż zwykle. :)
Spooky
1

Może komuś się przyda. W systemie Windows możesz pozwolić systemowi Windows wykonać zadanie, wywołując dir-command. Używam ścieżki absolutnej, na przykład E:/mydir/mysubdir.

<?php 
$mydir='E:/mydir/mysubdir';
$dir=str_replace('/','\\',$mydir);
$total = exec('dir '.$dir.' /b/a-d | find /v /c "::"');
Michel
źródło
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";
    } 

To powinno zadziałać, wejdź do katalogu w dirname. i niech magia się wydarzy.

oussama
źródło
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;
user3121984
źródło
0

W oparciu o zaakceptowaną odpowiedź, oto sposób POWTARZANIA liczenia wszystkich plików w katalogu:

iterator_count(
    new \RecursiveIteratorIterator(
        new \RecursiveDirectoryIterator('/your/directory/here/', \FilesystemIterator::SKIP_DOTS)
    )
)
Panni
źródło
0

Oto dość szybka funkcja PHP Linux. Trochę brudny, ale spełnia swoje zadanie!

$ dir - ścieżka do katalogu

$ type - f, d lub false (domyślnie)

f - zwraca tylko liczbę plików

d - zwraca tylko liczbę folderów

false - zwraca całkowitą liczbę plików i folderów

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

Możesz dostosować do swoich potrzeb.

Należy pamiętać, że to nie zadziała w systemie Windows.

GTodorov
źródło
-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);

proste dodaj gotowe ....

parajs dfsb
źródło
dodaj wyjaśnienie do swojego kodu, aby był jaśniejszy.
Alex.K.