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.

Bradly Spicer
fuente
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));
Baba
fuente
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'

JKirchartz
fuente
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 '..'.

intelis
fuente
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>
Laurent Brieu
fuente
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

fuente
¡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)
vbwx
fuente
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;
}

?>
Nirav Ranpara
fuente
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))
Philipp Werminghausen
fuente
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 '..').

Escalofriante
fuente
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 "::"');
Michel
fuente
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.

Oussama
fuente
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
fuente
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)
    )
)
Panni
fuente
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.

GTodorov
fuente
-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 ...

parajs dfsb
fuente
agregue alguna explicación a su código para que sea más claro.
Alex.K.