Как я могу использовать PHP, чтобы проверить, пуст ли каталог?

Я использую следующий скрипт для чтения каталога. Если в каталоге нет файла, он должен быть пустым. Проблема в том, что он просто продолжает говорить, что каталог пуст, хотя внутри есть файлы и наоборот.

<?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";
?>

14 ответов


кажется, что вам нужно scandir вместо glob, так как glob не может видеть скрытые файлы 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);
}
?>

обратите внимание, что этот код не является вершиной эффективности, так как нет необходимости читать все файлы только для того, чтобы сказать, если каталог пуст. Таким образом, лучшая версия будет

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

кстати, не используйте слова заменить boolean значения. Сама цель последнего состоит в том, чтобы сказать вам, если что-то пустое или нет. Ан

a === b

выражение уже возвращает Empty или Non Empty С точки зрения языка программирования, FALSE или TRUE соответственно-таким образом, вы можете использовать сам результат в структурах управления, таких как IF() без каких-либо промежуточных значений


Я думаю, используя FilesystemIterator должен быть самый быстрый и простой способ:

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

или использование доступа члена класса при создании экземпляра:

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

это работает, потому что новый FilesystemIterator первоначально указывала на первый файл в папке, если нет файлов в папке valid() вернутся false. (см. документацию здесь.)

как указал абдулманов.ilmir, дополнительно проверьте, если каталог существует перед использованием FileSystemIterator потому что иначе он бросит UnexpectedValueException.


Я нашел быстрое решение

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

использовать

if ($q == "Empty")

вместо

if ($q="Empty")

попробуйте это:

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

?>

вероятно, из-за оператора присваивания в if заявление.

изменения:

if ($q="Empty")

В:

if ($q=="Empty")

вот мое решение:

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

короткий и сладкий. Работает как заклинание.


для объектно-ориентированного подхода с использованием RecursiveDirectoryIterator С стандартная библиотека PHP (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;
    }
}

нет необходимости делать экземпляр вашего FileHelper всякий раз, когда вам это нужно, вы можете получить доступ к этому статическому методу, где вам это нужно:

FileHelper::isEmpty($dir);

на FileHelper класс может быть расширен с помощью других полезных методов копирования,удаления, переименования и т. д.

нет необходимости проверять действительность каталога внутри метод, потому что, если он недействителен, конструктор RecursiveDirectoryIterator появится UnexpectedValueException который охватывает эту часть достаточно.


просто исправьте свой код следующим образом:

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

@ Ваш Здравый Смысл

Я думаю, что ваш пример performant может быть более эффективным, используя строгое сравнение:

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

Я использую этот метод в моем плагине 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
}

оно работает специфическим расширением но легко изменен для того чтобы одеть ваши потребности путем извлекать "новую строку RegexIterator (". Граф $all_files.

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

        return count( $all_files );
    }

недавно у меня была аналогичная проблема, хотя самый высокий голосованный ответ на самом деле не работал для меня, поэтому мне пришлось придумать аналогичное решение. и опять же, это может быть не самый эффективный способ решить проблему,

Я создал функцию, подобную so

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

и использовал его для проверки пустых дрицетори, как так

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

вы можете использовать это:

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

первый вопрос, когда каталог пустой? В каталоге есть 2 файла с '.' и.' .'.
рядом с этим на Mac может быть файл".DS_Store'. Этот файл создается при добавлении в каталог какого-либо содержимого. Если эти 3 файла находятся в каталоге, вы можете сказать, что каталог пуст. Поэтому, чтобы проверить, пуст ли каталог (без тестирования, если $dir является каталогом):

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