I was reminded of this by dalecosp's TIL post about glob().
Some of my operating practices can leave me with lots of empty directories (create directories, add files, remove files, rinse and repeat, sometimes a dozen levels deep with thousands of files), so I figured I'd automate the job of pruning a directory tree to remove empty directories. Of course, "empty directories" includes directories that contain only empty directories.
It's just a command-line script: nothing fancy (it doesn't, for example, cope with symlinks). [font=monospace]php <path>/prune-tree.php <root of tree to prune>[/font].
// Current directory if none other specified.
$root = realpath($argv[1] ?? '.') or die("Root not found");
$queues = [[$root]];
$dirs = [[]];
while(!empty($queues))
{
foreach(array_pop($queues) as $d)
{
chdir($d);
echo $d,"\n";
$queues[] = $dirs[] = array_map('realpath', array_diff(glob('{,.}*', GLOB_ONLYDIR | GLOB_BRACE | GLOB_NOSORT), ['.','..']));
}
}
$dirs = array_merge(...$dirs);
usort($dirs, function($a, $b)
{
// Lazy way to ensure that child directories sort
// before their parents.
return strlen($b) - strlen($a);
});
echo "\n\n\n\n";
chdir($root);
$previous = '';
foreach($dirs as $dir)
{
if(count(scandir($dir, SCANDIR_SORT_NONE)) == 2) // '.' & '..'
{
echo $dir,"\n";
if(strncmp($dir, $previous, strlen($dir)) == 0)
{
// On Windows at least deleting empty
// directories immediately after deleting
// their contents is unreliable. At least
// that's how it looks. So wait a little
// after deleting the last child before
// deleting the parent.
usleep(10);
}
$previous = $dir;
rmdir($dir);
}
}