Contare quanti file nella directory PHP


108

Sto lavorando a un progetto leggermente nuovo. Volevo sapere quanti file ci sono in una determinata 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>

Questo è quello che ho finora (dalla ricerca). Tuttavia, non viene visualizzato correttamente? Ho aggiunto alcune note quindi sentiti libero di rimuoverle, sono solo così posso capirlo nel miglior modo possibile.

Se hai bisogno di ulteriori informazioni o ritieni di non averlo descritto abbastanza, non esitare a dichiararlo.


4
Sarebbe più breve usare un idioma come count(scandir("uploads/")) - 2quel ciclo.
mario

@mario Attento! scandir è carino, ma -2 non è esattamente il migliore - puoi essere in una directory root o la directory può avere directory all'interno - Laurent Brieu ha un bel controllo per ./ .. e directory :)
jave.web

Risposte:


263

Puoi semplicemente fare quanto segue:

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

22
+1 perché questo è carino, ma posso immaginare che sia abbastanza confuso / illeggibile per la maggior parte degli sviluppatori PHP. Vorrei seguire uno degli approcci nelle altre risposte.
user428517

Sebbene utile, non è stato molto facile da leggere quando ho posto la domanda. Detto questo, però, ho migliorato la mia conoscenza di php. Non ho votato al contrario.
Bradly Spicer

2
Questa dovrebbe essere la risposta accettata, a meno che il richiedente non desideri una versione più personalizzata, in cui potrebbe escludere determinati file.
Abhishek Madhani

1
Dato che le persone dicono che questo è fonte di confusione per alcuni sviluppatori, dovremmo aggiungere che se si utilizzano spazi dei nomi (poiché in ogni caso questo metodo richiede una versione recente di PHP), è necessario specificare anche lo spazio dei nomi: $ fi = new \ FilesystemIterator ( DIR , \ FilesystemIterator :: SKIP_DOTS);
graemeboy

2
Non è necessario passare la bandiera FilesystemIterator::SKIP_DOTScome impostazione predefinita comunque.
Eborbob

70

Puoi ottenere il conteggio dei file in questo modo:

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

dove si "*"trova puoi cambiarlo in un tipo di file specifico se lo desideri "*.jpg"o puoi fare più tipi di file come questo:

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

il GLOB_BRACEflag si espande {a, b, c} in modo che corrisponda a "a", "b" o "c"


3
Fantastico, ci sono molte possibilità con questo approccio per filtrare i file e contarli :) Creare un semplice ciclo e diverse condizioni sarebbe fantastico ... Ma come puoi includere altre directory all'interno di quelle directory e così via per contare tutto file ed escludere directory dal conteggio?
The Bumpaster

1
@TheBumpaster verificare questa domanda SO / risposte su come sottodirectory di scansione con glob: stackoverflow.com/q/12109042/276250
JKirchartz

2
Per chi questa soluzione non funziona, aggiungere __DIR__ . prima di "/path/to/dir/"( __DIR__ . "/path/to/dir/")
dnns

@ dnns In realtà l'aggiunta di qualsiasi cosa a /path/to/dirfallirebbe, perché prima /significa starting from root dir. Se ci fosse path/to/dir, allora sì, __DIR__ . '/path/to/dir'aiuterebbe (in questo caso devi usare /dopo__DIR__
Justinas

43

Prova questo.

// Directory
$directory = "/dir";

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

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

Senza contare il "." e '..'.


5
Forse $num_files = count($files) - 2;? A causa di .così come..
Havelock

Nota che conterà anche questi due: "." e ".."
Laurent Brieu

7
per sbarazzarsi di .e ..provare questo: $ files =array_diff( scandir("/dir"), array(".", "..") );
JKirchartz

2
array_slice(scandir($directory),2)
Spettrale

42

Avresti dovuto :

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

è lo stesso codice e non funziona: $ file = readdir ($ dh) dovrebbe essere $ file = readdir ($ dir)
Marco Pace

2
Sarebbe bello (e utile prima di tutto) sottolineare le differenze / errori che l'OP ha fatto in un testo minimalista.
Havelock

1
Ehi, grazie per questo. Non apparirà ancora per me, tuttavia sento che potrebbe avere a che fare con il mio foglio di stile o qualcosa del genere. Ad ogni modo, grazie mille per il tuo aiuto. Modifica: risolto :) Grazie mille!
Bradly Spicer

Non dimenticare di chiudere la directory :)
jave.web

16

La migliore risposta secondo me:

$num = count(glob("/exact/path/to/files/" . "*"));
echo $num;
  • Non conta. e ..
  • È una linea
  • Sono fiero di questo

Ho appena capito che puoi usare "cartella / *" se il tuo documento PHP è nella stessa directory!

Una battuta dovrebbe avere ricompense di reputazione x2 ... in realtà renderla x3
baron_bartek

1
Cosa intendi? "Non conta".
habibhassani

13

Dato che anche io avevo bisogno di questo, ero curioso di sapere quale alternativa fosse la più veloce.

Ho scoperto che - se tutto ciò che vuoi è un conteggio dei file - la soluzione di Baba è molto più veloce delle altre. Sono rimasto piuttosto sorpreso.

Provalo tu stesso:

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

Esecuzione di prova: (ovviamente, glob()non conta i file punto)

1: 99 (0.4815571308136 s)
2: 98 (0.96104407310486 s)
3: 99 (0.26513481140137 s)

Infine qual è il più veloce dato che non hai menzionato il risultato?
Alex

Ho detto che la soluzione di Baba è stata la più veloce, ma ovviamente avrei dovuto essere più chiaro sui risultati. Risolto ora.
vbwx

12

Demo funzionante

<?php

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

?>

Eviterei di chiamare glob () 2 volte se hai molti file nella directory. Invece assegnerei il risultato del primo glob alla variabile e userei count su questa variabile.
Konrad Gałęzowski

5

Io uso questo:

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

Questo è il primo che funziona per me, ma ha il problema che non ti dà la certezza che tutti i file contati siano immagini.
Sterling Diaz

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

array_slicefunziona in modo simile alla substrfunzione, solo che funziona con gli array.

Ad esempio, questo eliminerebbe le prime due chiavi dell'array dall'array:

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

E se ometti il ​​primo parametro, come nel primo esempio, l'array non conterrà le prime due coppie chiave / valore * ('.' E '..').


1
Questa è fondamentalmente la stessa risposta che è già stata proposta da altri poster. Puoi migliorare la tua risposta o aggiungere altre informazioni oltre a quelle già discusse?
Joe Miller,

Meglio .. ? Lascia che leggano il manuale di php.net un po 'più del solito. :)
Spettrale

1

Forse utile a qualcuno. Su un sistema Windows, puoi lasciare che Windows esegua il lavoro chiamando il comando dir. Uso un percorso assoluto, come 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";
    } 

Questo dovrebbe funzionare entra nella directory in dirname. e lascia che la magia accada.


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

Sulla base della risposta accettata, ecco un modo per contare tutti i file in una directory IN MODO RICORSIVO:

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

0

Ecco una funzione PHP Linux che è notevolmente veloce. Un po 'sporco, ma fa il suo lavoro!

$ dir - percorso della directory

$ type - f, do false (per impostazione predefinita)

f - restituisce solo il conteggio dei file

d - restituisce solo il conteggio delle cartelle

false: restituisce il conteggio totale di file e cartelle

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

Puoi modificare in base alle tue esigenze.

Tieni presente che questo non funzionerà su 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);

semplice aggiungi è fatto ....


aggiungi qualche spiegazione al tuo codice per renderlo più chiaro.
Alex.K.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.