Как я могу использовать PHP, чтобы проверить, является ли каталог пустым? - PullRequest
68 голосов
/ 21 сентября 2011

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

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

119 голосов
/ 21 сентября 2011

Кажется, что вам нужно 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 != "..") {
      closedir($handle);
      return FALSE;
    }
  }
  closedir($handle);
  return TRUE;
}

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

a === b

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

61 голосов
/ 17 сентября 2013

Я думаю, использование 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. (см. документацию здесь .)

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

9 голосов
/ 08 октября 2013

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

<?php
  $dir = 'directory'; // dir path assign here
  echo (count(glob("$dir/*")) === 0) ? 'Empty' : 'Not empty';
?>
7 голосов
/ 21 сентября 2011

используйте

if ($q == "Empty")

вместо

if ($q="Empty")
4 голосов
/ 12 апреля 2016

Для объектно-ориентированного подхода с использованием 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, который в достаточной степени покрывает эту часть.

4 голосов
/ 13 августа 2015

Это очень старая тема, но я подумал, что дам свои десять центов.Другие решения не работали для меня.

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

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

Коротко и мило.Работает как шарм.

4 голосов
/ 22 ноября 2011

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

<?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 голосов
/ 21 сентября 2011

Возможно из-за оператора присваивания в операторе if.

Изменение:

if ($q="Empty")

Кому:

if ($q=="Empty")
3 голосов
/ 30 августа 2013

@ Твой здравый смысл

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

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 голосов
/ 09 сентября 2013

Просто исправьте ваш код так:

<?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";
    }
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...