Удалить каталог с файлами в нем?

Интересно, что самый простой способ удалить каталог со всеми его файлами в нем?

Я использую rmdir(PATH . '/' . $value); для удаления папки, однако, если в ней есть файлы, я просто не могу ее удалить.

Ответ 1

В настоящее время доступно как минимум два варианта.

  1. Перед удалением папки удалите все ее файлы и папки (а это означает рекурсию!). Вот пример:

    public static function deleteDir($dirPath) {
        if (! is_dir($dirPath)) {
            throw new InvalidArgumentException("$dirPath must be a directory");
        }
        if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
            $dirPath .= '/';
        }
        $files = glob($dirPath . '*', GLOB_MARK);
        foreach ($files as $file) {
            if (is_dir($file)) {
                self::deleteDir($file);
            } else {
                unlink($file);
            }
        }
        rmdir($dirPath);
    }
    
  2. И если вы используете 5. 2+, вы можете использовать RecursiveIterator, чтобы сделать это, не выполняя рекурсию самостоятельно:

    $dir = 'samples' . DIRECTORY_SEPARATOR . 'sampledirtree';
    $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
    $files = new RecursiveIteratorIterator($it,
                 RecursiveIteratorIterator::CHILD_FIRST);
    foreach($files as $file) {
        if ($file->isDir()){
            rmdir($file->getRealPath());
        } else {
            unlink($file->getRealPath());
        }
    }
    rmdir($dir);
    

Ответ 2

Обычно я использую это, чтобы удалить все файлы в папке:

array_map('unlink', glob("$dirname/*.*"));

И тогда вы можете сделать

rmdir($dirname);

Ответ 3

какой самый простой способ удалить каталог со всеми его файлами в нем?

system("rm -rf ".escapeshellarg($dir));

Ответ 4

Короткая функция, выполняющая задание:

function deleteDir($path) {
    return is_file($path) ?
            @unlink($path) :
            array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}

Я использую его в классе Utils следующим образом:

class Utils {
    public static function deleteDir($path) {
        $class_func = array(__CLASS__, __FUNCTION__);
        return is_file($path) ?
                @unlink($path) :
                array_map($class_func, glob($path.'/*')) == @rmdir($path);
    }
}

С большой силой приходит большая ответственность. Когда вы вызываете эту функцию с пустым значением, она удаляет файлы, начиная с root (/). В качестве защиты вы можете проверить, пуст ли пуст:

function deleteDir($path) {
    if (empty($path)) { 
        return false;
    }
    return is_file($path) ?
            @unlink($path) :
            array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}

Ответ 5

Это более короткая версия отлично работает для меня

function deleteDirectory($dirPath) {
    if (is_dir($dirPath)) {
        $objects = scandir($dirPath);
        foreach ($objects as $object) {
            if ($object != "." && $object !="..") {
                if (filetype($dirPath . DIRECTORY_SEPARATOR . $object) == "dir") {
                    deleteDirectory($dirPath . DIRECTORY_SEPARATOR . $object);
                } else {
                    unlink($dirPath . DIRECTORY_SEPARATOR . $object);
                }
            }
        }
    reset($objects);
    rmdir($dirPath);
    }
}

Ответ 6

Как видно из большинства проголосовавших комментариев на странице руководства PHP о rmdir() (см. http://php.net/manual/es/function.rmdir.php), функция glob() не возвращается скрытые файлы. scandir() предоставляется в качестве альтернативы, которая решает эту проблему.

Алгоритм, описанный там (который в моем случае был похож на обаяние):

<?php 
    function delTree($dir)
    { 
        $files = array_diff(scandir($dir), array('.', '..')); 

        foreach ($files as $file) { 
            (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file"); 
        }

        return rmdir($dir); 
    } 
?>

Ответ 7

Вы можете использовать файловую систему Symfony (код):

// composer require symfony/filesystem

use Symfony\Component\Filesystem\Filesystem;

(new Filesystem)->remove($dir);

Однако я не мог удалить некоторые сложные структуры каталогов с помощью этого метода, поэтому сначала вы должны попробовать его, чтобы убедиться, что он работает правильно.


Я мог бы удалить указанную структуру каталогов, используя конкретную реализацию Windows:

$dir = strtr($dir, '/', '\\');
// quotes are important, otherwise one could
// delete "foo" instead of "foo bar"
system('RMDIR /S /Q "'.$dir.'"');


И просто для полноты, вот мой старый код:

function xrmdir($dir) {
    $items = scandir($dir);
    foreach ($items as $item) {
        if ($item === '.' || $item === '..') {
            continue;
        }
        $path = $dir.'/'.$item;
        if (is_dir($path)) {
            xrmdir($path);
        } else {
            unlink($path);
        }
    }
    rmdir($dir);
}

Ответ 8

Здесь у вас есть одна хорошая и простая рекурсия для удаления всех файлов в исходном каталоге, включая этот каталог:

function delete_dir($src) { 
    $dir = opendir($src);
    while(false !== ( $file = readdir($dir)) ) { 
        if (( $file != '.' ) && ( $file != '..' )) { 
            if ( is_dir($src . '/' . $file) ) { 
                delete_dir($src . '/' . $file); 
            } 
            else { 
                unlink($src . '/' . $file); 
            } 
        } 
    } 
    closedir($dir); 
    rmdir($src);

}

Функция основана на рекурсии, сделанной для копирования каталога. Вы можете найти эту функцию здесь: Скопировать все содержимое каталога в другое с помощью php

Ответ 9

Как насчет этого:

function recursiveDelete($dirPath, $deleteParent = true){
    foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
        $path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname());
    }
    if($deleteParent) rmdir($dirPath);
}

Ответ 10

Функция Glob не возвращает скрытые файлы, поэтому scandir может быть более полезным при попытке удалить рекурсивно дерево.

<?php
public static function delTree($dir) {
   $files = array_diff(scandir($dir), array('.','..'));
    foreach ($files as $file) {
      (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
    }
    return rmdir($dir);
  }
?>

Ответ 11

Я предпочитаю это, потому что он все еще возвращает TRUE, когда он преуспевает, и FALSE, когда он терпит неудачу, а также предотвращает ошибку, в которой пустые пути могут попробовать и удалить все из "/*"!!:

function deleteDir($path)
{
    return !empty($path) && is_file($path) ?
        @unlink($path) :
        (array_reduce(glob($path.'/*'), function ($r, $i) { return $r && deleteDir($i); }, TRUE)) && @rmdir($path);
}

Ответ 12

Лучшее решение для меня

my_folder_delete("../path/folder");

код:

function my_folder_delete($path) {
    if(!empty($path) && is_dir($path) ){
        $dir  = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs are not included,otherwise DISASTER HAPPENS :)
        $files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
        foreach ($files as $f) {if (is_file($f)) {unlink($f);} else {$empty_dirs[] = $f;} } if (!empty($empty_dirs)) {foreach ($empty_dirs as $eachDir) {rmdir($eachDir);}} rmdir($path);
    }
}

p.s. ЗАПОМНИТЬ!
не пропускайте ПУСТОЙ ЦЕННОСТИ в любой каталог, удаляющий функции!!! (резервируйте их всегда, иначе в один прекрасный день вы можете получить БЕДСТВИЙ!!)

Ответ 13

Litle bit изменить код alcuadrado - glob не видеть файлы с именем из таких точек, как .htaccess, поэтому я использую scandir и script удаляет себя - проверьте __FILE__.

function deleteDir($dirPath) {
    if (!is_dir($dirPath)) {
        throw new InvalidArgumentException("$dirPath must be a directory");
    }
    if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
        $dirPath .= '/';
    }
    $files = scandir($dirPath); 
    foreach ($files as $file) {
        if ($file === '.' || $file === '..') continue;
        if (is_dir($dirPath.$file)) {
            deleteDir($dirPath.$file);
        } else {
            if ($dirPath.$file !== __FILE__) {
                unlink($dirPath.$file);
            }
        }
    }
    rmdir($dirPath);
}

Ответ 14

Я хочу расширить ответ на @alcuadrado с комментариями @Vijit для обработки символических ссылок. Во-первых, используйте getRealPath(). Но тогда, если у вас есть какие-либо символические ссылки, которые являются папками, это провалится, поскольку он попытается вызвать rmdir по ссылке - так что вам нужна дополнительная проверка.

$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
    if ($file->isLink()) {
        unlink($file->getPathname());
    } else if ($file->isDir()){
        rmdir($file->getPathname());
    } else {
        unlink($file->getPathname());
    }
}
rmdir($dir);

Ответ 15

Использование DirectoryIterator эквивалент предыдущего ответа...

function deleteFolder($rootPath)
{   
    foreach(new DirectoryIterator($rootPath) as $fileToDelete)
    {
        if($fileToDelete->isDot()) continue;
        if ($fileToDelete->isFile())
            unlink($fileToDelete->getPathName());
        if ($fileToDelete->isDir())
            deleteFolder($fileToDelete->getPathName());
    }

    rmdir($rootPath);
}

Ответ 16

Этот работает для меня:

function removeDirectory($path) {
    $files = glob($path . '/*');
    foreach ($files as $file) {
        is_dir($file) ? removeDirectory($file) : unlink($file);
    }
    rmdir($path);
    return;
}

Ответ 17

Вы можете попробовать следующим образом:

/*
 * Remove the directory and its content (all files and subdirectories).
 * @param string $dir the directory name
 */
function rmrf($dir) {
    foreach (glob($dir) as $file) {
        if (is_dir($file)) { 
            rmrf("$file/*");
            rmdir($file);
        } else {
            unlink($file);
        }
    }
}

Ответ 18

Что-то вроде этого?

function delete_folder($folder) {
    $glob = glob($folder);
    foreach ($glob as $g) {
        if (!is_dir($g)) {
            unlink($g);
        } else {
            delete_folder("$g/*");
            rmdir($g);
        }
    }
}

Ответ 19

Удалить все файлы в папке
array_map('unlink', glob("$directory/*.*"));
Удалить все. * - Файлы в папке (без: "." И ".." )
array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
Теперь удалите папку самостоятельно
rmdir($directory)

Ответ 20

2 цента, чтобы добавить к ЭТОТ ответ выше, что отличное BTW

После того, как функция glob (или аналогичная) сканировала/прочитала каталог, добавьте условие, чтобы проверить, что ответ не пуст, или будет выведено предупреждение invalid argument supplied for foreach(). Так что...

if( ! empty( $files ) )
{
    foreach( $files as $file )
    {
        // do your stuff here...
    }
}

Моя полная функция (как метод объекта):

    private function recursiveRemoveDirectory( $directory )
    {
        if( ! is_dir( $directory ) )
        {
            throw new InvalidArgumentException( "$directory must be a directory" );
        }

        if( substr( $directory, strlen( $directory ) - 1, 1 ) != '/' )
        {
            $directory .= '/';
        }

        $files = glob( $directory . "*" );

        if( ! empty( $files ) )
        {
            foreach( $files as $file )
            {
                if( is_dir( $file ) )
                {
                    $this->recursiveRemoveDirectory( $file );
                }
                else
                {
                    unlink( $file );
                }
            }               
        }
        rmdir( $directory );

    } // END recursiveRemoveDirectory()

Ответ 21

Пример для сервера Linux: exec('rm -f -r ' . $cache_folder . '/*');

Ответ 22

Вот решение, которое работает идеально:

function unlink_r($from) {
    if (!file_exists($from)) {return false;}
    $dir = opendir($from);
    while (false !== ($file = readdir($dir))) {
        if ($file == '.' OR $file == '..') {continue;}

        if (is_dir($from . DIRECTORY_SEPARATOR . $file)) {
            unlink_r($from . DIRECTORY_SEPARATOR . $file);
        }
        else {
            unlink($from . DIRECTORY_SEPARATOR . $file);
        }
    }
    rmdir($from);
    closedir($dir);
    return true;
}

Ответ 23

<?php
  function rrmdir($dir) {
  if (is_dir($dir)) {
    $objects = scandir($dir);
    foreach ($objects as $object) {
      if ($object != "." && $object != "..") {
        if (filetype($dir."/".$object) == "dir") 
           rrmdir($dir."/".$object); 
        else unlink   ($dir."/".$object);
      }
    }
    reset($objects);
    rmdir($dir);
  }
 }
?>

Попробуйте выставить код из php.net

Работайте со мной отлично

Ответ 24

Для окон:

system("rmdir ".escapeshellarg($path) . " /s /q");

Ответ 25

Как и решение Playnox, но с элегантным встроенным каталогом:

function delete_directory($dirPath){
 if(is_dir($dirPath)){
  $objects=new DirectoryIterator($dirPath);
   foreach ($objects as $object){
    if(!$object->isDot()){
     if($object->isDir()){
      delete_directory($object->getPathname());
     }else{
      unlink($object->getPathname());
     }
    }
   }
   rmdir($dirPath);
  }else{
   throw new Exception(__FUNCTION__.'(dirPath): dirPath is not a directory!');
  }
 }

Ответ 26

Я не помню, откуда я скопировал эту функцию, но похоже, что она не указана и работает для меня.

function rm_rf($path) {
    if (@is_dir($path) && is_writable($path)) {
        $dp = opendir($path);
        while ($ent = readdir($dp)) {
            if ($ent == '.' || $ent == '..') {
                continue;
            }
            $file = $path . DIRECTORY_SEPARATOR . $ent;
            if (@is_dir($file)) {
                rm_rf($file);
            } elseif (is_writable($file)) {
                unlink($file);
            } else {
                echo $file . "is not writable and cannot be removed. Please fix the permission or select a new path.\n";
            }
        }
        closedir($dp);
        return rmdir($path);
    } else {
        return @unlink($path);
    }
}

Ответ 27

Это мой код, и он работает на 100%. Сначала вы должны удалить все файлы из папки, а затем сами поместить папку. Код не содержит вложенных папок, но вы можете легко включить этот код, чтобы включить также подпапку в папку $_POST.

    function delete_folder() {  
          $dirPath = $_POST['dirpath'];
          $TrackDir=opendir($dirPath);
          $i = 0;
           while ($file = readdir($TrackDir)) { 
                if ($file == "." || $file == "..") { } 
                    else {
                    $narray[$i]=$file;  
                    $i++;               
                } 
            }     
            $count1 = count($narray);

            if($count1 > 0){       
                $r=0;
                while($r < $count1){
                    $Filename = $narray[$r];
                    $myFile = $dirPath."/".$Filename;
                    unlink($myFile);                        
                    $r++;
                }   
                rmdir($dirPath);
            }else{
                rmdir($dirPath);
            }
            closedir($TrackDir);
}

Ответ 28

Просто и просто...

$dir ='pathtodir';
if (is_dir($dir)) {
  foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
    if ($filename->isDir()) continue;
    unlink($filename);
  }
  rmdir($dir);
}

Ответ 29

Как насчет этого?

function Delete_Directory($Dir) 
{
  if(is_dir($Dir))
  {
      $files = glob( $Dir . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned

      foreach( $files as $file )
      {
          Delete_Directory( $file );      
      }
      if(file_exists($Dir))
      {
          rmdir($Dir);
      }
  } 
  elseif(is_file($Dir)) 
  {
     unlink( $Dir );  
  }
}

Ссылка: https://paulund.co.uk/php-delete-directory-and-files-in-directory

Ответ 30

Если вы не уверены, что заданный путь является каталогом или файлом, вы можете использовать эту функцию для удаления пути

function deletePath($path) {
        if(is_file($path)){
            unlink($path);
        } elseif(is_dir($path)){
            $path = (substr($path, -1) !== DIRECTORY_SEPARATOR) ? $path . DIRECTORY_SEPARATOR : $path;
            $files = glob($path . '*');
            foreach ($files as $file) {
                deleteDirPath($file);
            }
            rmdir($path);
        } else {
            return false;
        }
}