it-swarm.cn

我该怎么用 PHP 检查目录是否为空?

我使用以下脚本来读取目录。如果目录中没有文件,则应该为空。问题是,它只是一直说目录是空的,即使内部有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";
?>
66
TheBlackBenzKid

看来你需要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;
}

顺便说一下,不要使用 words 来替换 boolean values。后者的目的是告诉你某些事情是否空洞。一个

a === b

表达式已经分别在编程语言EmptyFALSE方面返回TRUENon Empty - 所以,你可以在IF()这样的控制结构中使用非常结果而没有任何中间值

118
Your Common Sense

我认为使用 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

60
flu

我找到了一个快速解决方案

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

使用

if ($q == "Empty")

代替

if ($q="Empty")
7
Toto

试试这个:

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

可能是因为if语句中的赋值运算符。

更改:

if ($q="Empty")

至:

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

对于面向对象的方法,使用 RecursiveDirectoryIterator 来自 Standard PHP Library(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
Wilt

这是一个非常古老的线索,但我想我会给我十美分。其他解决方案对我不起作用。

这是我的解决方案:

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

简短又甜蜜。奇迹般有效。

4
narfie

@你的常识

我认为使用严格的比较可以使您的高性能示例更具性能:

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;
}
3
André Fiedler

只需更正您的代码:

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

你可以用这个:

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

我最近遇到了类似的问题,但是,最高投票的答案并不适用于我,因此,我不得不想出一个类似的解决方案。再次,这也可能不是解决问题的最有效方法,

我创建了一个这样的函数

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

并用它来检查空的dricetory像这样

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

我在我的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
}

它通过特定扩展工作,但可以通过删除“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

第一个问题是什么时候目录是空的?在目录中有2个文件'。'和'..'。
在Mac上的那个旁边可能有'.DS_Store'文件。将某种内容添加到目录时会创建此文件。如果这三个文件在目录中,您可能会说该目录为空。所以要测试一个目录是否为空(如果$ dir是一个目录,则不测试):

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