2012-07-16 108 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