Cuente cuántos archivos en el directorio PHP


106

Estoy trabajando en un proyecto un poco nuevo. Quería saber cuántos archivos hay en un directorio determinado.

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

Esto es lo que tengo hasta ahora (de buscar). Sin embargo, ¿no aparece correctamente? He agregado algunas notas, así que siéntase libre de eliminarlas, son solo para que pueda entenderlas lo mejor que pueda.

Si necesita más información o siente que no he descrito esto lo suficiente, no dude en indicarlo.


4
Sería más corto usar un modismo como count(scandir("uploads/")) - 2ese bucle.
mario

@mario ¡Cuidado! scandir es bueno, pero -2 no es exactamente el mejor - puede estar en un directorio raíz o el directorio puede tener directorios dentro - Laurent Brieu tiene una buena verificación de ./ .. y directorios :)
jave.web

Respuestas:


261

Simplemente puede hacer lo siguiente:

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

22
+1 porque es lindo, pero me imagino que es bastante confuso / ilegible para la mayoría de los desarrolladores de PHP. Iría con uno de los enfoques en las otras respuestas.
user428517

Aunque fue útil, no fue muy fácil de leer cuando hice la pregunta. Sin embargo, al decir eso, he mejorado mi conocimiento de php. No he votado a favor de esto.
Bradly Spicer

2
Esta debería ser la respuesta aceptada, a menos que el autor de la pregunta desee una versión más personalizada, donde podría excluir ciertos archivos.
Abhishek Madhani

1
Dado que la gente dice que esto es confuso para algunos desarrolladores, deberíamos agregar que si uno está usando espacios de nombres (ya que este método requiere una versión reciente de PHP en cualquier caso), entonces también se debe especificar el espacio de nombres: $ fi = new \ FilesystemIterator ( DIR , \ FilesystemIterator :: SKIP_DOTS);
graemeboy

2
No es necesario pasar la bandera, FilesystemIterator::SKIP_DOTSya que de todos modos es la predeterminada.
Eborbob

70

Puede obtener el recuento de archivos así:

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

donde "*"está, puede cambiar eso a un tipo de archivo específico si lo desea "*.jpg"o puede hacer varios tipos de archivo como este:

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

la GLOB_BRACEbandera se expande {a, b, c} para que coincida con 'a', 'b' o 'c'


3
Impresionante, hay muchas posibilidades con este enfoque para filtrar archivos y contarlos :) Crear un bucle simple y varias condiciones sería genial ... Pero, ¿cómo puedes incluir otros directorios dentro de esos directorios y así sucesivamente para contar todos? archivos y excluir directorios del recuento?
The Bumpaster

1
@TheBumpaster echa un vistazo a esta pregunta / respuesta SO sobre cómo escanear subdirectorios con glob: stackoverflow.com/q/12109042/276250
JKirchartz

2
Para quienes esta solución no funciona, agregue __DIR__ . antes "/path/to/dir/"( __DIR__ . "/path/to/dir/")
dnns

@dnns En realidad, agregar algo a /path/to/dirfallaría, porque primero /significa starting from root dir. Si lo hubiera path/to/dir, entonces sí, __DIR__ . '/path/to/dir'ayudaría (en este caso debe usar /después de__DIR__
Justinas

43

Prueba esto.

// Directory
$directory = "/dir";

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

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

Sin contar el '.' y '..'.


5
$num_files = count($files) - 2;¿ Quizás ? Porque .así como..
Havelock

Tenga en cuenta que también contará estos dos: '.' y '..'
Laurent Brieu

7
para deshacerse del .y ..probar esto: $ files =array_diff( scandir("/dir"), array(".", "..") );
JKirchartz

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

42

Deberías :

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

es el mismo código y no funciona: $ file = readdir ($ dh) debería ser $ file = readdir ($ dir)
Marco Pace

2
Sería bueno (y útil ante todo) señalar las diferencias / errores que ha cometido el OP en un texto minimalista.
Havelock

1
Hola, gracias por esto. Todavía no aparecerá para mí, sin embargo, creo que podría tener que ver con mi hoja de estilo o algo por el estilo. De cualquier manera muchas gracias por tu ayuda. Editar: arreglado :) ¡Muchas gracias!
Bradly Spicer

No olvide cerrar el directorio :)
jave.web

16

La mejor respuesta en mi opinión:

$num = count(glob("/exact/path/to/files/" . "*"));
echo $num;
  • No cuenta. y ...
  • Es un trazador de líneas
  • Estoy orgulloso de ello

¡Acabo de darme cuenta de que puede usar "carpeta / *" si su documento PHP está en el mismo directorio!

One liners debería tener recompensas de reputación x2 ... en realidad
hazlo

1
¿Qué quieres decir? "No cuenta".
habibhassani

13

Como yo también necesitaba esto, tenía curiosidad sobre qué alternativa era la más rápida.

Descubrí que, si todo lo que desea es un recuento de archivos, la solución de Baba es mucho más rápida que las demás. Me sorprendió bastante.

Pruébelo usted mismo:

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

Ejecución de prueba: (obviamente, glob()no cuenta los archivos de puntos)

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

Finalmente, ¿cuál es más rápido ya que no mencionaste el resultado?
Alex

Dije que la solución de Baba fue la más rápida, pero, por supuesto, debería haber sido más claro acerca de los resultados. Arreglado ahora.
vbwx

12

Demo de trabajo

<?php

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

?>

Evitaría llamar a glob () 2 veces si tiene muchos archivos en el directorio. En su lugar, asignaría el resultado del primer globo a la variable y usaría contar en esta variable.
Konrad Gałęzowski

5

Yo uso esto:

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

Este es el primero que me funciona, pero tiene el problema de que no te asegura que todos los archivos contados sean imágenes.
Sterling Diaz

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

array_slicefunciona de manera similar a la substrfunción, solo que funciona con matrices.

Por ejemplo, esto eliminaría las dos primeras claves de matriz de la matriz:

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

Y si omite el primer parámetro, como en el primer ejemplo, la matriz no contendrá los dos primeros pares clave / valor * ('.' Y '..').


1
Esta es básicamente la misma respuesta que ya han propuesto otros carteles. ¿Puede mejorar su respuesta o agregar más información que la que ya se ha discutido?
Joe Miller

Mejor .. ? Deje que lean el manual de php.net un poco más de lo habitual. :)
Spooky

1

Quizás sea útil para alguien. En un sistema Windows, puede dejar que Windows haga el trabajo llamando al comando dir. Yo uso una ruta absoluta, 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";
    } 

Esto debería funcionar ingrese al directorio en dirname. y deja que suceda la magia.


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

Según la respuesta aceptada, aquí hay una manera de contar todos los archivos en un directorio RECURSIVAMENTE:

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

0

Aquí hay una función PHP Linux que es considerablemente rápida. Un poco sucio, ¡pero hace el trabajo!

$ dir - ruta al directorio

$ tipo - f, d o falso (por defecto)

f - devuelve solo el recuento de archivos

d - devuelve solo el recuento de carpetas

falso: devuelve el recuento total de archivos y carpetas

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

Puede modificarlo para que se ajuste a sus necesidades.

Tenga en cuenta que esto no funcionará en 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);

simple agregar está hecho ...


agregue alguna explicación a su código para que sea más claro.
Alex.K.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.