Search code examples
phppermissionsmkdirrmdir

PHP mkdir not working after rmdir


I have a chunk of code that tests if a directory exists, deletes it if it exists, and creates a new directory over it. It should be fairly simple.

if(is_dir($directory)){
    $files = new RecursiveIteratorIterator(
              new RecursiveDirectoryIterator($directory,RecursiveDirectoryIterator::SKIP_DOTS),
              RecursiveIteratorIterator::CHILD_FIRST
            );
    foreach($files as $fileinfo){
        $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
        $todo($fileinfo->getRealPath());
    }
    rmdir($directory);
    //var_dump(is_dir($directory));
}

clearstatcache();
mkdir($directory,0744);  

If the directory does not exist yet, the mkdir() works just fine. But if the directory does exist, the rmdir() loop does its job, but PHP throws an error:

PHP Error[2]: mkdir(): Permission Denied

The commented var_dump() line shows me that PHP still thinks $directory is a directory even after the rmdir() call. So I use clearstatcache() to update it, but it still won't detect that the directory has been deleted. And when I look it up in the file system, the directory has in fact been deleted.

If I run the script again (while the directory is gone), it works just fine.

Can anyone figure out how to resolve this error? If it makes a difference, I am running this as a PHP command line script on my Win7/XAMPP dev environment.

edit:

Thanks to Wee Kiat and Phillip for the answer. The solution was to use unset($files) before rmdir() to close the recursive iterator, which was still keeping $directory open and causing mkdir() to choke. See their code below.


Solution

  • it appears that $files is the variable that is causing the problem, what you need to do is to unset $files after the foreach loop and you will be able to mkdir().

    if(is_dir($directory)){
        $files = new RecursiveIteratorIterator(
                  new RecursiveDirectoryIterator($directory,RecursiveDirectoryIterator::SKIP_DOTS),
                  RecursiveIteratorIterator::CHILD_FIRST
                );
            foreach($files as $fileinfo){
                $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
                $todo($fileinfo->getRealPath());
            }
    
        unset($files);
    
        rmdir($directory);
        //var_dump(is_dir($directory));
    }
    mkdir($directory,0744);  
    

    But i do not know why $files is causing the problem. any ideas?