1

On Stack Overflow there are several answers to the question of how to check if the directory is empty, but which is the fastest, which way is the most effective?


Answer 1: https://stackoverflow.com/a/7497848/4437206

function dir_is_empty($dir) {
  $handle = opendir($handle);
  while (false !== ($entry = readdir($handle))) {
    if ($entry != "." && $entry != "..") {
      closedir($handle); // <= I added this
      return FALSE;
    }
  }

  closedir($handle); // <= I added this
  return TRUE;
}

Answer 2: https://stackoverflow.com/a/18856880/4437206

$isDirEmpty = !(new \FilesystemIterator($dir))->valid();

Answer 3: https://stackoverflow.com/a/19243116/4437206

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

Or, there is a completely different way which is faster and more effective than these three above?

As for the Answer 1, please note that I added closedir($handle);, but I'm not sure if that's necessary (?).

EDIT: Initially I added closedir($dir); instead of closedir($handle);, but I corrected that as @duskwuff stated in his answer.

PeraMika
  • 3,539
  • 9
  • 38
  • 63
  • 2
    Who cares? Readability is far more important. – arkascha Jun 04 '18 at 22:41
  • 4
    Did you run a benchmark? – revo Jun 04 '18 at 22:42
  • @arkascha I care. – PeraMika Jun 04 '18 at 22:44
  • what about the other ways? –  Jun 04 '18 at 22:46
  • Unless the file system functions have changed, you could also just do a `count(scandir()) > 2` check in the function. – Jhecht Jun 04 '18 at 22:54
  • 1
    @Jhecht That's conceptually similar to the `glob()` solution, and will also perform poorly on large directories. –  Jun 04 '18 at 22:58
  • I'm unaware how PHP handles those sorts of things internally so if you know more of the actual implementation to `scandir` then I'll trust you on it. I was just saying it was another option. – Jhecht Jun 04 '18 at 22:59
  • 1
    @smith Noooo. Launching a new process is _much_ more "expensive", and I can't think of any single command which would do the job in a nondestructive fashion. –  Jun 04 '18 at 23:06

1 Answers1

4

The opendir()/readdir() and FilesystemIterator approaches are both conceptually equivalent, and perform identical system calls (as tested on PHP 7.2 running under Linux). There's no fundamental reason why either one would be faster than the other, so I would recommend that you run benchmarks if you need to microoptimize.

The approach using glob() will perform worse. glob() returns an array of all the filenames in the directory; constructing that array can take some time. If there are many files in the directory, it will perform much worse, as it must iterate through the entire contents of the directory.

Using glob() will also give incorrect results in a number of situations:

  • If $dir is a directory name which contains certain special characters, including *, ?, and [/]
  • If $dir contains only dotfiles (i.e, filenames starting with .)

As for the Answer 1, please note that I added closedir($dir);, but I'm not sure if that's necessary (?).

It's a good idea, but you've implemented it incorrectly. The directory handle that needs to be closed is $handle, not $dir.