2012-07-16 104 views
1

我有一段代码用于测试一个目录是否存在,如果它存在则删除它,并在其上创建一个新目录。它应该相当简单。PHP mkdir无法在rmdir之后工作

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); 

如果该目录还不存在,mkdir()工作得很好。但是,如果该目录不存在,rmdir()环,它的工作,但PHP抛出一个错误:

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

的评论var_dump()行让我发现,PHP仍然认为$directory是连rmdir()电话后的目录。所以我使用clearstatcache()来更新它,但它仍然不会检测到目录已被删除。当我在文件系统中查找它时,该目录实际上已被删除。

如果我再次运行脚本(而目录不见了),它工作得很好。

任何人都可以弄清楚如何解决这个错误?如果它有所作为,我将它作为我的Win7/XAMPP开发环境中的PHP命令行脚本运行。

编辑:

感谢Wee Kiat和Phillip的回答。解决方法是在rmdir()之前使用unset($files)来关闭递归迭代器,该递归迭代器仍然保持$directory打开并导致mkdir()呛。请参阅下面的代码。

+2

“权限被拒绝”是一个明确的错误 – 2012-07-16 22:26:46

+1

如果您传递给'clearstatcache();'?你可以把'var_dump(is_dir());'直接放在'mkdir()'之前吗? – nickb 2012-07-16 22:34:00

+0

@ Dagon - 在这种情况下,拒绝权限不明确,因为它只给出错误的50%的时间。 @nickb - 在'clearstatcache()'之前或之后,'var_dump()'在两个位置给出相同的输出。看起来'clearstatcache()'没有做任何事情。 – penco 2012-07-16 23:19:53

回答

2

看来$ files是导致问题的变量,您需要做的是在foreach循环之后取消设置$ files,您将能够使用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); 

但我不知道为什么$文件导致的问题。有任何想法吗?

+2

嗯,我猜RecursiveIteratorIterator在目录上仍然有一个打开的句柄,直到PHP关闭,其中RecursiveIteratorIterator被销毁并且之后目录被删除。这会导致mkdir()失败,但看起来好像该目录已被删除(因为它是在脚本完成之后)。因此,在正确的时间销毁RecursiveIteratorIterator解决了这个问题。 (尽管如此,我会建议使用'unset($ files);')。 – PhilMasterG 2012-07-17 04:59:12

+0

非常感谢菲利普的解释,我根据你的建议使用未设置($文件)编辑解决方案 – 2012-07-17 05:14:05

+0

你们真是太棒了!非常感谢。我昨天浪费了大约4个小时的时间...... – penco 2012-07-17 13:26:42