4

I've got a folder, filled with both empty and full folders.

I want to iterate over all of them, figure out if they are empty, and if so, remove them. I've seen some questions that are appliccable, but I cannot figure out the total solution:

There must be some easy sure-fire way to do this, using the new PHP5 functions?

Something like (pseudocode full of errors)

<?php
$dir = new DirectoryIterator('/userfiles/images/models/');
foreach ($dir as $fileinfo) {
    if (!$fileinfo->isDot()) {
         if(!(new \FilesystemIterator($fileinfo))->valid()) {
              rmdir($fileinfo);
         }
    }
}
?>
Community
  • 1
  • 1
chocolata
  • 3,258
  • 5
  • 31
  • 60
  • So do you want a solution with `DirectoryIterator` or could it also be something with `glob` or so? – Rizier123 Feb 23 '15 at 12:50
  • 2
    Thx for your answer. I'd like the optimal solution, taking into account I'm on a shared hosting. So maybe the solution with the least requirements would do? – chocolata Feb 23 '15 at 12:53

1 Answers1

8

This should work for you:

Here I just get all directory's from a specific path with glob() (PHP 4 >= 4.3.0, PHP 5). Then I iterate through every directory and check if it is empty.

If it is empty I remove it with rmdir() else I check if there is another direcotry in it and call the function with the new directory

<?php

    function removeEmptyDirs($path, $checkUpdated = false, $report = false) {
        $dirs = glob($path . "/*", GLOB_ONLYDIR);

        foreach($dirs as $dir) {
            $files = glob($dir . "/*");
            $innerDirs = glob($dir . "/*", GLOB_ONLYDIR);
            if(empty($files)) {
                if(!rmdir($dir))
                    echo "Err: " . $dir . "<br />";
               elseif($report)
                    echo $dir . " - removed!" . "<br />";
            } elseif(!empty($innerDirs)) {
                removeEmptyDirs($dir, $checkUpdated, $report);
                if($checkUpdated)
                    removeEmptyDirs($path, $checkUpdated, $report);
            }
        }

    }


?>

removeEmptyDirs

(PHP 4 >= 4.3.3, PHP 5)
removeEmptyDirs — Removes empty directory's

void removeEmptyDirs( string $path [, bool $checkUpdated = false [, bool $report = false ]] )

Description

The removeEmptyDirs() function goes through a directory and removes every empty directory

Parameters

path
  The Path where it should remove empty directorys

checkUpdated
  If it is set to TRUE it goes through each directory again if one directory got removed

report
  If it is set to TRUE the function outputs which directory get's removed

Return Values

None

As an example:

If $checkUpdated is TRUE structures like this get's deleted entirely:

- dir
   | - file.txt
   | - dir
        | - dir

Result:

- dir
   | - file.txt

If it is FALSE like in default the result would be:

- dir
   | - file.txt
   | - dir  //See here this is still here

If $report is TRUE you get a output like this:

test/a - removed!
test/b - removed!
test/c - removed!

Else you get no output

Rizier123
  • 58,877
  • 16
  • 101
  • 156
  • 1
    Thank you so much for your extensive answer! I'm testing it out as we speak and will let you know my findings. This is why I love SO! – chocolata Feb 23 '15 at 15:10
  • @maartenmachiels You're welcome. Let me know if it worked for you – Rizier123 Feb 23 '15 at 15:11
  • Unfortunately the script doesn't function as envisioned in my scenario. Going through my logs, I notice the following error: `mod_fcgid: stderr: PHP Fatal error: Can't use function return value in write context in /var/www/vhosts/xxx.xxx/subdomains/beta/httpdocs/tools/remove_empty.php on line 13` Any clue on how to salvage this? Line 13 is `if(empty(glob($dir . "/*"))) {`. My PHP version is 5.3.3. Could that be an issue? The path I am using: `/var/www/vhosts/xxx.xxx/subdomains/beta/httpdocs/userfiles/images/test2` – chocolata Feb 23 '15 at 15:17
  • Thanks! I've tried again. One test succesful, and one failed... Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 523800 bytes) in `/var/www/vhosts/xxx.xxx/subdomains/beta/httpdocs/tools/remove_empty.php on line 21` Without recursion enabled, it seems to go very smoothly. I have no problem executing the script multiple times if needed. What do you think? :-) – chocolata Feb 23 '15 at 15:33
  • @maartenmachiels Weird, if you don't have the second parameter true it only calls the function once. But since 1 test was successful, maybe it was a one time thing if you can't reproduce it. (Can you reproduce it?) – Rizier123 Feb 23 '15 at 15:36
  • The first test was without subfolders, and recursion enabled. The second test was with 3 levels of subfolders. Will try again. – chocolata Feb 23 '15 at 15:37
  • New findings: with only 2 levels, it seems to work fine. One notice only: `Warning: rmdir(/var/www/vhosts/xxx.xxx/subdomains/beta/httpdocs/userfiles/images/test2/testo): No such file or directory in /var/www/vhosts/xxx.xxx/subdomains/beta/httpdocs/tools/remove_empty.php on line 16 Err: /var/www/vhosts/xxx.xxx/subdomains/beta/httpdocs/userfiles/images/test2/testo` – chocolata Feb 23 '15 at 15:41
  • 1
    @maartenmachiels Okay, really weird I tested it and I couldn't reproduce neither the memory error (tried with 600 folders) nor this warning with the dir not found. (Make sure your path is correct and or try with: `./your path`) – Rizier123 Feb 23 '15 at 15:46