web-dev-qa-db-fra.com

Comment puis-je utiliser PHP vérifier si un répertoire est vide?

J'utilise le script suivant pour lire un répertoire. S'il n'y a pas de fichier dans le répertoire, il devrait être vide. Le problème, c'est que le répertoire est toujours vide, même s'il y a des fichiers ARE à l'intérieur, et inversement.

<?php
$pid    =       $_GET["prodref"];
$dir    =       '/assets/'.$pid.'/v';
$q     =        (count(glob("$dir/*")) === 0) ? 'Empty' : 'Not empty';

    if ($q=="Empty")
        echo "the folder is empty"; 
    else
        echo "the folder is NOT empty";
?>
66
TheBlackBenzKid

Il semble que vous ayez besoin de scandir au lieu de glob, car glob ne peut pas voir les fichiers cachés unix.

<?php
$pid = basename($_GET["prodref"]); //let's sanitize it a bit
$dir = "/assets/$pid/v";

if (is_dir_empty($dir)) {
  echo "the folder is empty"; 
}else{
  echo "the folder is NOT empty";
}

function is_dir_empty($dir) {
  if (!is_readable($dir)) return NULL; 
  return (count(scandir($dir)) == 2);
}
?>

Notez que ce code n'est pas le summum de l'efficacité, car il n'est pas nécessaire de lire tous les fichiers uniquement pour savoir si le répertoire est vide. Donc, la meilleure version serait

function dir_is_empty($dir) {
  $handle = opendir($dir);
  while (false !== ($entry = readdir($handle))) {
    if ($entry != "." && $entry != "..") {
      closedir($handle);
      return FALSE;
    }
  }
  closedir($handle);
  return TRUE;
}

En passant, n'utilisez pas words pour remplacer les valeurs boolean. Le but même de ce dernier est de vous dire si quelque chose est vide ou non. Un

a === b

expression renvoie déjà Empty ou Non Empty en termes de langage de programmation, FALSE ou TRUE respectivement - vous pouvez donc utiliser le résultat même dans des structures de contrôle telles que IF() sans valeur intermédiaire

118
Your Common Sense

Je pense que l’utilisation de FilesystemIterator devrait être le moyen le plus rapide et le plus simple:

// PHP 5 >= 5.3.0
$iterator = new \FilesystemIterator($dir);
$isDirEmpty = !$iterator->valid();

Ou en utilisant l’accès des membres de la classe à l’instanciation:

// PHP 5 >= 5.4.0
$isDirEmpty = !(new \FilesystemIterator($dir))->valid();

Cela fonctionne car une nouvelle FilesystemIterator pointe initialement sur le premier fichier du dossier. S'il n'y a aucun fichier dans le dossier, valid() renverra false. (voir documentation ici .)

Comme indiqué par abdulmanov.ilmir, vérifiez éventuellement si le répertoire existe avant d’utiliser la variable FileSystemIterator, faute de quoi elle lancera une variable UnexpectedValueException.

60
flu

J'ai trouvé une solution rapide

<?php
  $dir = 'directory'; // dir path assign here
  echo (count(glob("$dir/*")) === 0) ? 'Empty' : 'Not empty';
?>
9
Frank

utilisation 

if ($q == "Empty")

au lieu de

if ($q="Empty")
7
Toto

Essaye ça:

<?php
$dirPath = "Add your path here";

$destdir = $dirPath;

$handle = opendir($destdir);
$c = 0;
while ($file = readdir($handle)&& $c<3) {
    $c++;
}

if ($c>2) {
    print "Not empty";
} else {
    print "Empty";
} 

?>
4
Drmzindec

Probablement à cause de l'opérateur d'affectation dans la déclaration if.

Changement:

if ($q="Empty")

À:

if ($q=="Empty")
4
Robik

Pour une approche orientée objet utilisant RecursiveDirectoryIterator à partir de Standard PHP Bibliothèque (SPL) .

<?php

namespace My\Folder;

use RecursiveDirectoryIterator;

class FileHelper
{
    /**
     * @param string $dir
     * @return bool
     */
    public static function isEmpty($dir)
    {
        $di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
        return iterator_count($di) === 0;
    }
}

Pas besoin de créer une instance de votre FileHelper chaque fois que vous en avez besoin, vous pouvez accéder à cette méthode statique à tout moment, comme ceci:

FileHelper::isEmpty($dir);

La classe FileHelper peut être étendue avec d'autres méthodes utiles pour copier, supprimer, renommer, etc.

Il n'est pas nécessaire de vérifier la validité du répertoire à l'intérieur de la méthode car s'il est invalide, le constructeur de la variable RecursiveDirectoryIterator lancera une variable UnexpectedValueException qui couvre suffisamment cette partie.

4
Wilt

C'est un très vieux fil, mais je pensais donner mes dix sous. Les autres solutions ne fonctionnaient pas pour moi.

Voici ma solution:

function is_dir_empty($dir) {
    foreach (new DirectoryIterator($dir) as $fileInfo) {
        if($fileInfo->isDot()) continue;
        return false;
    }
    return true;
}

Court et doux. Fonctionne comme un charme.

4
narfie

@ Votre sens commun

Je pense que votre exemple performant pourrait être plus performant en utilisant une comparaison stricte:

function is_dir_empty($dir) {
  if (!is_readable($dir)) return null; 
  $handle = opendir($dir);
  while (false !== ($entry = readdir($handle))) {
    if ($entry !== '.' && $entry !== '..') { // <-- better use strict comparison here
      closedir($handle); // <-- always clean up! Close the directory stream
      return false;
    }
  }
  closedir($handle); // <-- always clean up! Close the directory stream
  return true;
}
2
André Fiedler

Corrigez votre code comme ceci:

<?php
    $pid = $_GET["prodref"];
    $dir = '/assets/'.$pid.'/v';
    $q = count(glob("$dir/*")) == 0;

    if ($q) {
        echo "the folder is empty"; 
    } else {
        echo "the folder is NOT empty";
    }
?>
2
Alessandro.Vegna

Vous pouvez utiliser ceci:

function isEmptyDir($dir)
{
    return (($files = @scandir($dir)) && count($files) <= 2);
}
0
karrtojal

J'ai eu un problème similaire récemment, bien que la réponse la plus élevée votée ne fonctionnait pas vraiment pour moi et que je devais donc proposer une solution similaire. et encore une fois, cela peut aussi ne pas être le moyen le plus efficace de résoudre le problème, 

J'ai créé une fonction comme

function is_empty_dir($dir)
   {
       if (is_dir($dir))
       {
            $objects = scandir($dir);
            foreach ($objects as $object)
            {
                if ($object != "." && $object != "..")
                {
                    if (filetype($dir."/".$object) == "dir")
                    {
                         return false;
                    } else { 
                        return false;
                    }
                }
            }
            reset($objects);
            return true;
       }

et l'a utilisé pour vérifier le vide dricetory comme si

if(is_empty_dir($path)){
            rmdir($path);
        }
0
user28864

J'utilise cette méthode dans mon plugin Wordpress CSV 2 POST.

    public function does_folder_contain_file_type( $path, $extension ){
        $all_files  = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ) );

        $html_files = new RegexIterator( $all_files, '/\.'.$extension.'/' );  

        foreach( $html_files as $file) {
            return true;// a file with $extension was found
        }   

    return false;// no files with our extension found
}

Il fonctionne par extension spécifique mais est facilement modifiable en fonction de vos besoins en supprimant "new RegexIterator (" line. Count. $ All_files.

    public function does_folder_contain_file_type( $path, $extension ){
        $all_files  = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ) );

        return count( $all_files );
    }
0
Ryan Bayne

La première question est de savoir quand un répertoire est-il vide? Dans un répertoire, il y a 2 fichiers le "." et '..'.
À côté de cela sur un Mac, il y a peut-être le fichier '.DS_Store'. Ce fichier est créé lorsqu'un type de contenu est ajouté au répertoire. Si ces 3 fichiers sont dans le répertoire, vous pouvez dire que le répertoire est vide . Donc, pour vérifier si un répertoire est vide (sans vérifier si $ dir est un répertoire):

function isDirEmpty( $dir ) {
  $count = 0;
  foreach (new DirectoryIterator( $dir ) as $fileInfo) {
     if ( $fileInfo->isDot() || $fileInfo->getBasename() == '.DS_Store' ) {
        continue;
     }
     $count++;
  }
  return ($count === 0);
}
0
Harm