4

I'm trying to create a function which will run periodically to delete any old "user" folders which don't have an active user. This is the function I have:

function delete_temp_user_files() {
    $dir = $_SERVER['DOCUMENT_ROOT'] . "/users/";
    $dir_files = array();
    $dir_files = scandir($dir);
    foreach ($dir_files as $username) {
        if ($username == "." || $username == "..") continue;
        if (!user_exist($username)) {
            $dir1 = $_SERVER['DOCUMENT_ROOT'] . "/users/" . $username;
            if (!is_dir($dir1)) continue;
            if (file_exists($dir1)) unlink($dir1);
        }
    }
}

But when it tries to delete the directory I get the error "Warning: unlink(/path/to/users/delete1/): Is a directory in /page.php on line..." I know the directory exists because I can see it in the directory, and it found it using scandir() anyway.

I use unlink to delete these same folders in other scripts and it works fine. The directories aren't empty so I can't user rmdir().

I'm not familiar with permissions or anything like that, is this some kind of issue with that? And do I need to worry about permissions if I only ever use PHP scripts to delete files and folders (like when the user clicks on the delete button which runs the script I wrote)?

UPDATE:

After scouring the web I finally found how to delete a directory and it's not easy lol Add this function into the previous function and it works!

function delete_dir($directory) {
    foreach(glob("{$directory}/*") as $file)
    {
        if(is_dir($file)) { 
            delete_dir($file);
        } else {
            unlink($file);
        }
    }
    rmdir($directory);
}
thinkofacard
  • 491
  • 1
  • 6
  • 19
  • 3
    you cannot delete folders before files in PHP. remove the files then remove the folder(s) - unlink is for files, not folders - refs: http://php.net/manual/en/function.unlink.php - http://php.net/manual/en/function.rmdir.php - http://php.net/manual/en/function.chmod.php – Funk Forty Niner Aug 04 '15 at 14:49
  • you may however, be able to achieve this via ftp instead, but I can't confirm this right now. Edit: one solution found via ftp http://stackoverflow.com/a/8595188/ if you ever want to go that route. – Funk Forty Niner Aug 04 '15 at 15:04
  • For updated code; If you have linux server, you can try `exec('rm -R ' . $dirname)`. `exec` allow you to execute shell commands. http://php.net/manual/en/function.exec.php – Kapil Sharma Aug 04 '15 at 15:29
  • Note to the author update: glob doesn't return hidden files, therefore is better to use scandir. –  Jan 13 '18 at 19:30

3 Answers3

7

unlink is used to delete files, use rmdir

Please note, you must first delete all files in directory.

Also, your code is very dangerous. Assume with time, you have 100,000 users so will have 100,000 folders. Can you imagine how much time will this line take?

foreach ($dir_files as $username) {

Please think alternate way.

Good way, don't delete users from your database. find users who didn't login since 6 months (say) and disable them. this way, your loop is smaller.

Kapil Sharma
  • 10,135
  • 8
  • 37
  • 66
  • [yeah, which is what I said....](http://stackoverflow.com/questions/31812511/im-getting-is-a-directory-error-when-trying-unlink-directory#comment51550373_31812511) – Funk Forty Niner Aug 04 '15 at 14:55
  • @Fred-ii- yes its same. When I started writing answer, your comment wasn't there. Only difference, I gave answer (because it was straight forward) and you posted comment. – Kapil Sharma Aug 04 '15 at 15:32
2

There is a function given on the rmdir documentation page :

 function rrmdir($dir) { 
   if (is_dir($dir)) { 
     $objects = scandir($dir); 
     foreach ($objects as $object) { 
       if ($object != "." && $object != "..") { 
         if (filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object); 
       } 
     } 
     reset($objects); 
     rmdir($dir); 
   } 
 }

Sure it will make your life easier.

dlegall
  • 412
  • 2
  • 5
0

I know that this is a late answer, but I solved it by checking if the file exists or not.

I'm using database for the path of the file. So you may try an example code below.

if(!empty($course->picture)){
  // unlink here
}
Blues Clues
  • 1,694
  • 3
  • 31
  • 72