PHPを使用してディレクトリが空かどうかを確認するにはどうすればよいですか?


83

次のスクリプトを使用してディレクトリを読み取ります。ディレクトリにファイルがない場合は、空と表示されます。問題は、内部にファイルがあるにもかかわらず、ディレクトリが空であると言い続けることです。その逆も同様です。

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

8
これは、ifステートメントのタイプミスにすぎません。単一の=(割り当て)の代わりに==(比較)を使用します。
バススラグター2011

回答:


134

scandirglobはunixの隠しファイルを見ることができないため、globの代わりに必要なようです。

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

表現すでにリターンEmptyNon Empty言語、プログラミングの観点FALSETRUE、それぞれを-ので、あなたのような制御構造に非常に結果を使用することができますIF()任意の中間値なし


2
フォルダからすべてのファイルを削除したのに、フォルダが空ではないと表示されているため、両方のコードが間違っていると思います... Linuxでthumbs.dbなどの隠しファイルをチェックする方法はありますか?
TheBlackBenzKid 2011

FTPフォルダは..と。と言うと思います。ファイル内は空です。..やthumbs.dbなどを確認して削除するにはどうすればよいですか?
TheBlackBenzKid 2011

globはLinuxの隠しファイルをサポートしていません。あなたがそれらを望むなら、あなたは削除された答えのようにopenirソリューションに行かなければなりません
あなたの常識

globの代わりにscandirが必要なようです。
あなたの常識

2
テスト環境を作成してください。スクリプトがあるのと同じフォルダに空のディレクトリを作成します。作り$dir = 'testfolder';手で。次に、このコードを実行します。debugは、何が問題になっているのかを確認するために、可能な限り多くの情報を出力しています。$dir = 'testfolder';var_dump(scan_dir($dir));このディレクトリに何があるかを教えてくれます
あなたの常識

69

FilesystemIteratorを使用するのが、最も速くて簡単な方法だと思います。

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

または、インスタンス化時にクラスメンバーアクセスを使用します。

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

これが機能FilesystemIteratorするのは、newが最初にフォルダ内の最初のファイルを指すためです。フォルダ内にファイルがない場合は、valid()を返しfalseます。(ここのドキュメントを参照してください。)

abdulmanov.ilmirで指摘されているように、オプションでディレクトリが存在するかどうかを確認してFileSystemIteratorから使用してください。存在しない場合はUnexpectedValueException。がスローされます。


7
うーん...これのために私の腰がチクチクする。
マットフレッチャー

3
$dir存在しない場合は、例外がスローされることを考慮する必要があります。
abdulmanov.ilmir 2017年

10

簡単な解決策を見つけました

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

単純なケースのためにphp5.2で使用するソリューション。
ルーカスモーガン

globには隠しファイルが表示されないことに注意してください。すなわち「.htaccessファイル」を含むディレクトリには、このコードを持つ空として扱われます
rosell.dk

7

使用する

if ($q == "Empty")

の代わりに

if ($q="Empty")

5

標準PHPライブラリ(SPL)RecursiveDirectoryIteratorからを使用するオブジェクト指向アプローチの場合。

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

これを試して:

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

?>

ありがとう!私はそれを非常に迅速に書き、その最初の投稿はここにあります@Piotr Nowicki
Drmzindec 2011年

確かに、それは私の市民の義務です;-) StackOverflowへようこそ!
Piotr Nowicki 2011年

4

おそらくifステートメントの代入演算子が原因です。

変化する:

if ($q="Empty")

に:

if ($q=="Empty")

4

これは非常に古いスレッドですが、私は10セントをあげると思いました。他の解決策は私にはうまくいきませんでした。

これが私の解決策です:

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

短くて甘い。チャームのように機能します。


4

@あなたの常識

厳密な比較を使用すると、パフォーマンスの高い例のパフォーマンスが向上すると思います。

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

1
クリーンアップに関する良い点:return falseケースはそれを処理していません;-)
ビートクリステン

ヒントは@BeatChristenThx!修正しました。
アンドレフィードラー2016

私が理解していないのは、「。」と比較するときは厳密な比較を使用する方がよいとあなたが言う理由です。および「..」。readdir()関数は常に文字列(またはfalse)を返すため、要点がわかりません。また、自分の後でクリーンアップすることは常に良い考えであると付け加えたいと思います。$ handle変数がスコープ外になると戻った後、closedir()が自動的に発生すると思いますが、私は小さなテストプログラムを作成しました。そしてそうではありません。群れのような他のものが自動的に起こるので、これは奇妙です。
soger 2018年

@AndréFiedlerあなたは天才で、才能があり、責任感のある人です。他のすべての回答では、最初にファイルの総数を計算し、次にカウントが0より大きいかどうかを確認します。ただし、ディレクトリにファイルが1つでも含まれている場合、それは空ではありません。
AshishDoneriya19年

4

私が使用した:

if(is_readable($dir)&&count(scandir($dir))==2) ... //then the dir is empty

3

count大きな配列では関数の使用が遅くなる可能性があります。issetこれまでになく高速です

これはPHP> = 5.4.0で正しく機能します(ここの変更ログを参照)

function dir_is_empty($path){ //$path is realpath or relative path

    $d = scandir($path, SCANDIR_SORT_NONE ); // get dir, without sorting improve performace (see Comment below). 

    if ($d){

        // avoid "count($d)", much faster on big array. 
        // Index 2 means that there is a third element after ".." and "."

        return !isset($d[2]); 
    }

    return false; // or throw an error
}

それ以外の場合は、@ Your Common Senseソリューションを使用して、RAMにファイルリストをロードしないようにすることをお勧めします

SCANDIR_SORT_NONEオプションを使用してこの回答を改善するために、@ sogerにも感謝して投票してください。


3
パフォーマンスが心配な場合は、SCANDIR_SORT_NONEパラメーターも追加することをお勧めします。
soger

2

次のようにコードを修正してください。

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

0

このメソッドは、Wordpress CSV 2POSTプラグインで使用しています。

    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
}

特定の拡張子で機能しますが、「newRegexIterator(」行を削除することでニーズに合わせて簡単に変更できます。$ all_filesを数えます。

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

        return count( $all_files );
    }

0

私は最近同様の問題を抱えていましたが、最高得票数の回答は実際には機能しなかったため、同様の解決策を考え出す必要がありました。また、これも問題を解決するための最も効率的な方法ではない可能性があります。

私はそのような関数を作成しました

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

あなたはこれを使うことができます:

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

0

最初の質問は、ディレクトリがいつ空になるかです。ディレクトリには、「。」という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

@あなたの常識、@ Enyby

コードのいくつかの改善:

function dir_is_empty($dir) {
    $handle = opendir($dir);
    $result = true;
    while (false !== ($entry = readdir($handle))) {
        if ($entry != "." && $entry != "..") {
            $result = false;
            break 2;
        }
    }
    closedir($handle);
    return $result;
}

結果を格納するために変数を使用し、それをtrueに設定します。
ディレクトリが空の場合、返されるファイルは。だけです。および..(Linuxサーバーでは、必要に応じてMacの条件を拡張できます)。したがって、条件はtrueです。
次に、resultの値がfalseに設定され、break 2がifループとwhileループを終了して、次に実行されるステートメントがclosedirになります。
したがって、whileループは、ディレクトリが空であるかどうかに関係なく、終了する前に3つの円しかありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.