2010-12-20 12 views
4

私はこのコードを再帰的にファイルやディレクトリを削除する必要があります。それはうまく動作しますが、少し問題があります。 $ path =/var/www/foo /ならば、fooの中のすべてを削除しますが、fooは削除しません。私もfooディレクトリを削除したい。何か案が?再帰的削除

public function delete($path) { 
    if(!file_exists($path)) { 
     throw new RecursiveDirectoryException('Directory doesn\'t exist.'); 
    } 

    $directoryIterator = new DirectoryIterator($path); 

    foreach($directoryIterator as $fileInfo) { 
     $filePath = $fileInfo->getPathname(); 

     if(!$fileInfo->isDot()) { 
      if($fileInfo->isFile()) { 
       unlink($filePath); 
      } 
      else if($fileInfo->isDir()) { 
       if($this->emptyDirectory($filePath)) { 
        rmdir($filePath); 
       } 
       else { 
        $this->delete($filePath); 
        rmdir($filePath); 
       } 
      } 
     } 
    } 
} 
+0

@stereofrog:ほぼすべて? – Bobby

答えて

3

最後にrmdirが欠落しています。この場合、私は確信して、あなたはそこに何を得るのパス検証を願って、また

public function delete($path) { 
    //snip 

    foreach($directoryIterator as $fileInfo) { 
     //snip 
       else { 
        $this->delete($filePath); 
       } 
      } 
     } 
    } 

    rmdir($path); 
} 

$this->delete($path); 
rmdir($path); 

それとも、このようなforeach -loopを変更することができます:あなたはこのよう$this->delete($path)後にそれを呼び出すことができますいずれか「私のウェブ空間上のすべてを削除」-functionのように(ユーザーに表示されます。私は意味、誰かがそこに/etc/に合格した場合、あなたは多くの楽しみを持っています。

+1

はい、 '$ this-> delete($ filePath);'の後に削除することができます。 –

+0

いいえ...理由はわかりませんが、$ path(ディレクトリ)はもう存在しません。ありがとうございました。 – thom

+0

@ Spiny Norman:私はforeach-loopの後にそれを追加するという考え方でもっと考えていました。 – Bobby

-1
function delete($path){ 
    if(!file_exists($path)) { 
     throw new RecursiveDirectoryException('Directory doesn\'t exist.'); 
    } 

    $directoryIterator = new DirectoryIterator($path); 

    foreach($directoryIterator as $fileInfo) { 
     $filePath = $fileInfo->getPathname(); 

     if(!$fileInfo->isDot()) { 
      if($fileInfo->isFile()) { 
       unlink($filePath); 
      } 
      else if($fileInfo->isDir()) { 
       if($this->emptyDirectory($filePath)) { 
        rmdir($filePath); 
       } 
       else { 
        $this->delete($filePath); 
        rmdir($filePath); 
       } 
      } 
     } 
    } 
    rmdir($path); 
} 

12

なぜあなたの機能で再発しますか?

public function delete($path) { 
    $it = new RecursiveIteratorIterator(
     new RecursiveDirectoryIterator($path), 
     RecursiveIteratorIterator::CHILD_FIRST 
    ); 
    foreach ($it as $file) { 
     if (in_array($file->getBasename(), array('.', '..'))) { 
      continue; 
     } elseif ($file->isDir()) { 
      rmdir($file->getPathname()); 
     } elseif ($file->isFile() || $file->isLink()) { 
      unlink($file->getPathname()); 
     } 
    } 
    rmdir($path); 
} 

親要素の前に子供を超えるRII::CHILD_FIRST反復するので、動作します。したがって、ディレクトリに到達するまでには、空でなければなりません。

実際のエラーは、ディレクトリを削除した場所が原因です。内部ディレクトリでは、親の繰り返しでそれを行います。つまり、ルートディレクトリは決して削除されません。私は、ローカルの削除の繰り返しでそれを行うことをお勧めします:

public function delete($path) { 
    if(!file_exists($path)) { 
     throw new RecursiveDirectoryException('Directory doesn\'t exist.'); 
    } 

    $directoryIterator = new DirectoryIterator($path); 

    foreach($directoryIterator as $fileInfo) { 
     $filePath = $fileInfo->getPathname(); 
     if(!$fileInfo->isDot()) { 
      if($fileInfo->isFile()) { 
       unlink($filePath); 
      } elseif($fileInfo->isDir()) { 
       if($this->emptyDirectory($filePath)) { 
        rmdir($filePath); 
       } else { 
        $this->delete($filePath); 
       } 
      } 
     } 
    } 
    rmdir($path); 
} 

2つの変更に注意してください。私たちは、反復の中の空のディレクトリだけを削除しています。その上に$this->delete()を呼び出すと、削除が処理されます。 2番目の変更は、メソッドの最後に、最終的なrmdirの追加...

+0

ありがとう、私はそれを試してみる... – thom

+0

それは働いた。ありがとうございました。 – thom

+1

これはLinuxで動作しますが、Windowsでは空であった* parent *フォルダを削除するときに、そのコンテンツの再帰的削除のために、「許可が拒否されました」というエラーが表示されました。関数の 'rmdir($ path)' * out *を取らなければなりません。 '$ path = realpath(" ./ test "); delete($ path); rmdir($ path); ' – nevvermind

0

この

解除($のDirectoryIterator)をしてみてくださいです。 rmdir($ filePath);

関連する問題