Рекурсивное удаление

У меня есть этот код для рекурсивного удаления файлов и каталогов. Он отлично работает, но имеет небольшую проблему. Если $ path = / var / www / foo / it удалит все внутри 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); } } } } } 

Почему даже рекурсия в вашей функции?

 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 выполняет RII::CHILD_FIRST над 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); } 

Обратите внимание на два изменения. Мы удаляем только пустые каталоги внутри итерации. Вызов $this->delete() на нем будет обрабатывать удаление для вас. Второе изменение – добавление окончательного rmdir в конце метода …

Вам не хватает одного последнего rmdir . Вы можете вызвать его после $this->delete($path) следующим образом:

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

Или вы можете изменить foreach -loop следующим образом:

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

Кроме того, я надеюсь, что вы подтвердите, какие пути вы получите там, если это видно пользователю (например, «Удалить все на моем веб-пространстве»). Я имею в виду, вам будет очень весело, если кто-то пройдет /etc/ туда.

попробуй это

unset ($ directoryIterator); RmDir ($ Filepath);

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

?