How can I use PHP to check if a directory is empty?

PhpDirectory

Php Problem Overview


I am using the following script to read a directory. If there is no file in the directory it should say empty. The problem is, it just keeps saying the directory is empty even though there ARE files inside and vice versa.

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

Php Solutions


Solution 1 - Php

It seems that you need scandir instead of glob, as glob can't see unix hidden files.

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

Note that this code is not the summit of efficiency, as it's unnecessary to read all the files only to tell if directory is empty. So, the better version would be

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

By the way, do not use words to substitute boolean values. The very purpose of the latter is to tell you if something empty or not. An

a === b

expression already returns Empty or Non Empty in terms of programming language, false or true respectively - so, you can use the very result in control structures like IF() without any intermediate values

Solution 2 - Php

I think using the FilesystemIterator should be the fastest and easiest way:

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

Or using class member access on instantiation:

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

This works because a new FilesystemIterator will initially point to the first file in the folder - if there are no files in the folder, valid() will return false. (see documentation here.)

As pointed out by abdulmanov.ilmir, optionally check if the directory exists before using the FileSystemIterator because otherwise it'll throw an UnexpectedValueException.

Solution 3 - Php

I found a quick solution

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

Solution 4 - Php

use

if ($q == "Empty")

instead of

if ($q="Empty")

Solution 5 - Php

For a object oriented approach using the RecursiveDirectoryIterator from the 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;
    }
}

No need to make an instance of your FileHelper whenever you need it, you can access this static method wherever you need it like this:

FileHelper::isEmpty($dir);

The FileHelper class can be extended with other useful methods for copying, deleting, renaming, etc.

There is no need to check the validity of the directory inside the method because if it is invalid the constructor of the RecursiveDirectoryIterator will throw an UnexpectedValueException which that covers that part sufficiently.

Solution 6 - Php

This is a very old thread, but I thought I'd give my ten cents. The other solutions didn't work for me.

Here is my solution:

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

Short and sweet. Works like a charm.

Solution 7 - Php

I used:

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

Solution 8 - Php

Probably because of assignment operator in if statement.

Change:

if ($q="Empty")

To:

if ($q=="Empty")

Solution 9 - Php

Try this:

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

?>

Solution 10 - Php

@ Your Common Sense

I think your performant example could be more performant using strict comparison:

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

Solution 11 - Php

Function count usage maybe slow on big array. isset is ever faster

This will work properly on PHP >= 5.4.0 (see Changelog here)

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
}

Otherwise, using @Your Common Sense solution it's better for avoid load file list on RAM

Thanks and vote up to @soger too, to improve this answer using SCANDIR_SORT_NONE option.

Solution 12 - Php

Just correct your code like this:

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

Solution 13 - Php

Even an empty directory contains 2 files . and .., one is a link to the current directory and the second to the parent. Thus, you can use code like this:

$files = scandir("path to directory/");
if(count($files) == 2) {
  //do something if empty
}

Solution 14 - Php

I use this method in my Wordpress CSV 2 POST plugin.

    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
}

It works by specific extension but is easily changed to suit your needs by removing "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 );
    }

Solution 15 - Php

I had a similar problem recently, although, the highest up-voted answer did not really work for me, hence, I had to come up with a similar solution. and again this may also not be the most efficient way to go about the problem,

I created a function like 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;
       }

and used it to check for empty dricetory like so

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

Solution 16 - Php

You can use this:

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

Solution 17 - Php

The first question is when is a directory empty? In a directory there are 2 files the '.' and '..'.
Next to that on a Mac there maybe the file '.DS_Store'. This file is created when some kind of content is added to the directory. If these 3 files are in the directory you may say the directory is empty. So to test if a directory is empty (without testing if $dir is a directory):

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

Solution 18 - Php

@Your Common Sense,@Enyby

Some improvement of your code:

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

I use a variable for storing the result and set it to true.
If the directory is empty the only files that are returned are . and .. (on a linux server, you could extend the condition for mac if you need to) and therefore the condition is true.
Then the value of result is set to false and break 2 exit the if and the while loop so the next statement executed is closedir.
Therefore the while loop will only have 3 circles before it will end regardless if the directory is empty or not.

Solution 19 - Php

$is_folder_empty = function(string $folder) : bool {
    if (!is_dir($folder))
        return TRUE;

    // This wont work on non linux OS.
    return is_null(shell_exec("ls {$folder}"));
};
$is_folder_empty2 = function(string $folder) : bool {
    if (!is_dir($folder))
        return TRUE;
    
    // Empty folders have two files in it. Single dot and
    // double dot.
    return count(scandir($folder)) === 2;
};

var_dump($is_folder_empty('/tmp/demo'));
var_dump($is_folder_empty2('/tmp/demo'));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTheBlackBenzKidView Question on Stackoverflow
Solution 1 - PhpYour Common SenseView Answer on Stackoverflow
Solution 2 - PhpfluView Answer on Stackoverflow
Solution 3 - PhpFrankView Answer on Stackoverflow
Solution 4 - PhpTotoView Answer on Stackoverflow
Solution 5 - PhpWiltView Answer on Stackoverflow
Solution 6 - PhpnarfieView Answer on Stackoverflow
Solution 7 - PhpLuca C.View Answer on Stackoverflow
Solution 8 - PhpRobikView Answer on Stackoverflow
Solution 9 - PhpDrmzindecView Answer on Stackoverflow
Solution 10 - PhpAndré FiedlerView Answer on Stackoverflow
Solution 11 - PhpOscar ZarrusView Answer on Stackoverflow
Solution 12 - PhpAlessandro.VegnaView Answer on Stackoverflow
Solution 13 - PhprainbowdogView Answer on Stackoverflow
Solution 14 - PhpRyan BayneView Answer on Stackoverflow
Solution 15 - Phpuser28864View Answer on Stackoverflow
Solution 16 - PhpkarrtojalView Answer on Stackoverflow
Solution 17 - PhpHarmView Answer on Stackoverflow
Solution 18 - PhpAlexander BehlingView Answer on Stackoverflow
Solution 19 - PhpFrancisco LuzView Answer on Stackoverflow