Conte quantos arquivos no diretório PHP


108

Estou trabalhando em um projeto ligeiramente novo. Queria saber quantos arquivos existem em um determinado diretório.

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

Isso é o que eu tenho até agora (de pesquisar). No entanto, ele não está aparecendo corretamente? Eu adicionei algumas notas, então sinta-se à vontade para removê-las, elas são apenas para que eu possa entendê-las da melhor maneira possível.

Se precisar de mais informações ou se sentir que não descrevi o suficiente, sinta-se à vontade para declará-lo.


4
Seria mais curto usar um idioma como count(scandir("uploads/")) - 2aquele loop.
mario,

@mario Cuidado! scandir é bom, mas -2 não é exatamente o melhor - você pode estar em um diretório raiz ou o diretório pode ter diretórios dentro - Laurent Brieu fez uma boa verificação de ./ .. e diretórios :)
jave.web

Respostas:


263

Você pode simplesmente fazer o seguinte:

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

22
+1 porque isso é bonito, mas posso imaginar que seja bastante confuso / ilegível para a maioria dos desenvolvedores de PHP. Eu iria com uma das abordagens nas outras respostas.
user428517

Embora útil, não foi muito fácil de ler quando fiz a pergunta. Dito isso, melhorei meu conhecimento sobre php. Eu não votei a favor.
Bradly Spicer

2
Esta deve ser a resposta aceita, a menos que o solicitante deseje uma versão mais customizada, onde poderia excluir determinados arquivos.
Abhishek Madhani,

1
Dado que as pessoas estão dizendo que isso é confuso para alguns desenvolvedores, devemos acrescentar que, se alguém estiver usando namespaces (uma vez que este método requer uma versão recente do PHP em qualquer caso), deve-se também especificar o namespace: $ fi = new \ FilesystemIterator ( DIR , \ FilesystemIterator :: SKIP_DOTS);
graemeboy

2
Você não precisa passar o sinalizador, FilesystemIterator::SKIP_DOTSpois é o padrão de qualquer maneira.
Eborbob

70

Você pode obter a contagem de arquivos assim:

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

onde "*"é, você pode alterá-lo para um tipo de arquivo específico, se desejar, "*.jpg"ou pode fazer vários tipos de arquivo como este:

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

o GLOB_BRACEsinalizador expande {a, b, c} para corresponder a 'a', 'b' ou 'c'


3
Incrível, há muitas possibilidades com esta abordagem para filtrar arquivos, bem como contá-los :) Criar um loop simples e várias condições seria ótimo ... Mas como você pode incluir outros diretórios dentro desses diretórios e assim por diante para contar todos arquivos e excluir diretórios da contagem?
The Bumpaster

1
@TheBumpaster confira esta pergunta / respostas do SO sobre como digitalizar subdiretórios com glob: stackoverflow.com/q/12109042/276250
JKirchartz

2
Para quem esta solução não funcionar, adicione __DIR__ . antes "/path/to/dir/"( __DIR__ . "/path/to/dir/")
dnns

@dnns Na verdade, adicionar qualquer coisa a /path/to/diriria falhar, porque primeiro /significa starting from root dir. Se houvesse path/to/dir, então sim, __DIR__ . '/path/to/dir'ajudaria (neste caso você deve usar /depois__DIR__
Justinas

43

Experimente isso.

// Directory
$directory = "/dir";

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

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

Sem contar o '.' e '..'.


5
Talvez $num_files = count($files) - 2;? Por causa da .bem como..
Havelock

Observe que também contará estes dois: '.' e '..'
Laurent Brieu,

7
para se livrar do .e ..tente isto: $ files =array_diff( scandir("/dir"), array(".", "..") );
JKirchartz

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

42

Você devia ter :

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

é o mesmo código e não funciona: $ file = readdir ($ dh) deve ser $ file = readdir ($ dir)
Marco Pace

2
Seria bom (e útil antes de tudo) apontar as diferenças / erros que o OP cometeu em um texto minimalista.
Havelock,

1
Olá, obrigado por isso. Ainda não aparecerá para mim, entretanto eu sinto que pode ter a ver com minha folha de estilo ou algo parecido. De qualquer forma, muito obrigado pela ajuda. Edit: Fixed :) Muito obrigado!
Bradly Spicer,

Não se esqueça de fechar o diretório :)
jave.web

16

A melhor resposta na minha opinião:

$num = count(glob("/exact/path/to/files/" . "*"));
echo $num;
  • Isso não conta. e ..
  • É uma linha
  • Estou orgulhoso disso

Acabei de perceber que você pode usar "folder / *" se seu documento PHP estiver no mesmo diretório!

Uma linha deve ter recompensas de reputação x2 ... na verdade, torná-la x3
baron_bartek

1
O que você quer dizer? "Não conta".
habibhassani

13

Como eu também precisava disso, fiquei curioso para saber qual alternativa era a mais rápida.

Descobri que - se tudo o que você quiser é uma contagem de arquivos - a solução de Baba é muito mais rápida do que as outras. Fiquei bastante surpreso.

Experimente você mesmo:

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

Execução de teste: (obviamente, glob()não conta arquivos de ponto)

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

Por fim, qual é mais rápido porque você não mencionou o resultado?
Alex

Eu disse que a solução de Baba foi mais rápida, mas é claro que deveria ter sido mais claro sobre os resultados. Corrigido agora.
vbwx

12

Demonstração de trabalho

<?php

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

?>

Eu evitaria chamar glob () 2 vezes se você tiver muitos arquivos no diretório. Em vez disso, atribuiria o resultado do primeiro glob à variável e usaria a contagem nessa variável.
Konrad Gałęzowski

5

Eu uso isso:

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

Este é o primeiro que funciona para mim, mas tem o problema de não te dar garantia de que todos os arquivos contados são imagens.
Sterling Diaz

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

array_slicefunciona de forma semelhante à substrfunção, mas funciona com matrizes.

Por exemplo, isso cortaria as duas primeiras chaves de array de array:

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

E se você omitir o primeiro parâmetro, como no primeiro exemplo, a matriz não conterá os dois primeiros pares de chave / valor * ('.' E '..').


1
Esta é basicamente a mesma resposta que já foi proposta por outros participantes. Você pode melhorar sua resposta ou adicionar mais informações além das já discutidas?
Joe Miller,

Melhor .. ? Deixe-os ler o manual php.net um pouco mais do que o normal. :)
Assustador de

1

Talvez seja útil para alguém. Em um sistema Windows, você pode permitir que o Windows faça o trabalho chamando o comando dir. Eu uso um caminho absoluto, como 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";
    } 

Isso deve funcionar, insira o diretório em dirname. e deixe a mágica acontecer.


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

Com base na resposta aceita, aqui está uma maneira de contar todos os arquivos em um diretório RECURSIVAMENTE:

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

0

Aqui está uma função do PHP Linux que é consideravelmente rápida. Um pouco sujo, mas dá conta do recado!

$ dir - caminho para o diretório

$ type - f, d ou false (por padrão)

f - retorna apenas a contagem de arquivos

d - retorna apenas a contagem de pastas

false - retorna a contagem total de arquivos e pastas

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

Você pode ajustar para atender às suas necessidades.

Observe que isso não funcionará no 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);

simples adicionar está feito ....


adicione alguma explicação ao seu código para torná-lo mais claro.
Alex.K.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.