web-dev-qa-db-ja.com

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

GlobはUnixの隠しファイルを見ることができないため、globではなくscandirが必要なようです。

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

ところで、booleanの値の代わりにwordsを使用しないでください。後者のまさに目的は、何かが空かどうかを伝えることです。あ

a === b

式は、プログラミング言語の観点から、それぞれEmptyまたはNon EmptyFALSEまたはTRUEをそれぞれ返します。したがって、IF()中間値なし

120

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がスローされます。

62
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 from 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

これは非常に古いスレッドですが、私は10セントを与えると思いました。他のソリューションは私にとってはうまくいきませんでした。

私の解決策は次のとおりです。

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

これを使用できます:

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

そしてそれを使って空っぽの薬味を

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(」行を削除することにより、ニーズに合わせて簡単に変更できます。$ 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'があります。このファイルは、何らかの種類のコンテンツがディレクトリに追加されたときに作成されます。これらの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);
}
0
Harm