Удаление всех файлов из папки с помощью PHP?

Например, у меня была папка с именем «Temp», и я хотел удалить или очистить все файлы из этой папки с помощью PHP. Могу я это сделать?


person getaway    schedule 04.01.2011    source источник
comment
Хорошо, что на этот вопрос был дан ответ ниже, прежде чем он был помечен как повторяющийся. Приведенные ниже ответы намного лучше, чем ответ на связанный вопрос. Плюс вопрос в другом, этот вопрос просит очистить каталог, а не удалить.   -  person Bart Burg    schedule 24.11.2014
comment
Да, это другой вопрос, на который есть разные ответы. Он не должен быть помечен как дубликат.   -  person Daniel Bingham    schedule 13.05.2015


Ответы (15)


$files = glob('path/to/temp/*'); // get all file names
foreach($files as $file){ // iterate files
  if(is_file($file)) {
    unlink($file); // delete file
  }
}

Если вы хотите удалить «скрытые» файлы, такие как .htaccess, вы должны использовать

$files = glob('path/to/temp/{,.}*', GLOB_BRACE);
person Floern    schedule 04.01.2011
comment
Также есть DirectoryIterator или DirectoryRecursiveIterator. - person Eugene; 04.01.2011
comment
Хотя это очевидно, я бы упомянул, что, например, 'path / to / temp / *. Txt' удалит только файлы txt и так далее. - person Tertium; 31.03.2015
comment
Это также работает для относительных путей? Допустим, полный путь - / var / www / html / folder_and_files_to_delete / А сценарий удаления находится в /var/www/html/delete_folders_and_files.php. Могу я просто взять в качестве пути folder_and_files_to_delete? - person yoano; 31.03.2016
comment
@yoano да, конечно, если относительный путь правильный. - person Floern; 31.03.2016
comment
Можно ли использовать glob, если в каталоге есть десятки тысяч или сотни тысяч файлов? - person Dave Heq; 08.08.2017
comment
@Floern, что, если я также хочу удалить подпапки и содержимое внутри них, текущий код удаляет только файлы, а не папки внутри - person Akshay Shrivastav; 11.02.2020
comment
что насчет папок? пустая папка, если хотите удалить - person user889030; 20.09.2020

Если вы хотите удалить все из папки (включая подпапки), используйте эту комбинацию array_map, unlink и glob:

array_map( 'unlink', array_filter((array) glob("path/to/temp/*") ) );

Этот вызов также может обрабатывать пустые каталоги (спасибо за подсказку, @mojuba!)

person Stichoza    schedule 20.11.2012
comment
Лучший ответ, спасибо. Чтобы избежать уведомлений, я бы также сделал glob("...") ?: [] (PHP 5.4+), потому что для пустого каталога glob() возвращает false. - person mojuba; 25.01.2013
comment
Он удаляет все файлы в текущей папке, но возвращает предупреждение для вложенных папок и не удаляет их. - person Key-Six; 05.03.2014
comment
Объединение ответов Стихозы и Моджубы: array_map('unlink', ( glob( "path/to/temp/*" ) ? glob( "path/to/temp/*" ) : array() ) ); - person Ewout; 23.04.2014
comment
@Ewout: Даже если мы объединим ответы Stichoza и Moujuba, поскольку ваш give возвращает то же предупреждение для вложенных папок и не удаляет их - person Sulthan Allaudeen; 21.05.2014
comment
К сожалению, при этом не удаляются вложенные папки. - person tmarois; 16.08.2016
comment
Чтобы подавить предупреждения об ошибках, используйте @array_map('unlink', glob("path/to/temp/*")); - person tmarois; 16.08.2016
comment
@mojuba Я кодил на PHP довольно долгое время, но никогда не знал, что мы можем $b = $a?:[] вещи - раньше я $b = $a ? $a : [] Большое спасибо за это !! - person Jay Dadhania; 04.04.2020

Вот более современный подход с использованием стандартной библиотеки PHP (SPL).

$dir = "path/to/directory";
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ( $ri as $file ) {
    $file->isDir() ?  rmdir($file) : unlink($file);
}
return true;
person Yamiko    schedule 03.07.2014
comment
Это прекрасно работает, когда у вас нет доступа по SSH, а FTP занимает буквально часов, чтобы рекурсивно удалить множество файлов и папок ... с этими строками я удалил 35000 файлов менее чем за 3 секунды! - person guari; 28.04.2017
comment
Для пользователей PHP 7.1: необходимо использовать $ file- ›getRealPath () вместо $ file. В противном случае PHP выдаст сообщение об ошибке, в котором говорится, что для отмены связи требуется путь, а не экземпляр SplFileInfo. - person KeineMaster; 20.09.2018
comment
Это решение сбой сервера - localhost, а также онлайн-сервер. Не лучшее решение для меня. Спасибо. - person Kamlesh; 29.09.2020

Этот код из http://php.net/unlink:

/**
 * Delete a file or recursively delete a directory
 *
 * @param string $str Path to file or directory
 */
function recursiveDelete($str) {
    if (is_file($str)) {
        return @unlink($str);
    }
    elseif (is_dir($str)) {
        $scan = glob(rtrim($str,'/').'/*');
        foreach($scan as $index=>$path) {
            recursiveDelete($path);
        }
        return @rmdir($str);
    }
}
person Poelinca Dorin    schedule 04.01.2011

См. readdir и unlink.

<?php
    if ($handle = opendir('/path/to/files'))
    {
        echo "Directory handle: $handle\n";
        echo "Files:\n";

        while (false !== ($file = readdir($handle)))
        {
            if( is_file($file) )
            {
                unlink($file);
            }
        }
        closedir($handle);
    }
?>
person StampedeXV    schedule 04.01.2011

Предполагая, что у вас есть папка с ОЧЕНЬ большим количеством файлов, читающих их все, а затем удаляющих в два этапа, это не так эффективно. Я считаю, что наиболее эффективный способ удаления файлов - это просто использовать системную команду.

Например, в Linux я использую:

exec('rm -f '. $absolutePathToFolder .'*');

Или это, если вы хотите рекурсивное удаление без необходимости писать рекурсивную функцию

exec('rm -f -r '. $absolutePathToFolder .'*');

те же самые команды существуют для любой ОС, поддерживаемой PHP. Имейте в виду, что это ЭФФЕКТИВНЫЙ способ удаления файлов. $ absolutePathToFolder ДОЛЖЕН быть проверен и защищен перед запуском этого кода, и должны быть предоставлены разрешения.

person Dario Corno    schedule 27.09.2015
comment
Немного небезопасно использовать этот метод, если $absolutePatToFolder когда-либо пуст - person Lawrence Cherone; 04.01.2017
comment
@LawrenceCherone Другие альтернативы более безопасны? - person robsch; 03.04.2017
comment
@LawrenceCherone Я надеюсь, что в настоящее время никто не запускает php с правами root. Если серьезно, я ожидаю, что ввод будет безопасным, как и все вышеперечисленные функции. - person Dario Corno; 03.04.2017
comment
Решения, получившие наибольшее количество голосов, не работают в средах разработки, где www или www-data не являются владельцем. Администратор сервера должен убедиться, что установлены надлежащие права для папки. exec - бесценный инструмент для выполнения задач, обладающий большой мощностью и т. д. stackoverflow.com/a/2765171/418974 - person Christian Bonato; 14.04.2017
comment
@LawrenceCherone, вы совершенно правы, мой ответ был предназначен для очень конкретной ситуации, просто по соображениям производительности. Изменил свой ответ в соответствии с вашими заметками. - person Dario Corno; 28.09.2017
comment
может захотеть использовать / * на всякий случай :-) - person commonpike; 21.12.2018
comment
Я бы также добавил проверку по $ absolutePatToFolder, чтобы убедиться, что он не пустой if (strlen ($ absolutePatToFolder)) {/ * приведенный выше код здесь * /} - person Oliver M Grech; 26.02.2019
comment
@ChristianBonato согласился с тем, что команды оболочки - лучший вариант. но почему владельцем не может быть www или www-data в среде разработки? - person David; 11.10.2019
comment
@ Дэвид - Я не говорю, что не может. Мой комментарий относился к случаям, когда папка или файлы не принадлежат www или www-data (или любому другому пользователю веб-сервера Unix). PHP запускает exec как пользователя веб-сервера. Поэтому exec может не работать с папкой или файлами с другим владельцем. - person Christian Bonato; 13.10.2019
comment
Немного менее агрессивно exec("find ./path/ -iname '*.html' -exec rm {} \;"); - person NVRM; 17.06.2020

Самый простой и лучший способ удалить все файлы из папки в PHP

$files = glob('my_folder/*'); //get all file names
foreach($files as $file){
    if(is_file($file))
    unlink($file); //delete file
}

Получил этот исходный код отсюда - http://www.codexworld.com/delete-all-files-from-folder-using-php/.

person JoyGuru    schedule 21.06.2016

Функция unlinkr рекурсивно удаляет все папки и файлы по заданному пути, убедившись, что она не удаляет сам скрипт.

function unlinkr($dir, $pattern = "*") {
    // find all files and folders matching pattern
    $files = glob($dir . "/$pattern"); 

    //interate thorugh the files and folders
    foreach($files as $file){ 
    //if it is a directory then re-call unlinkr function to delete files inside this directory     
        if (is_dir($file) and !in_array($file, array('..', '.')))  {
            echo "<p>opening directory $file </p>";
            unlinkr($file, $pattern);
            //remove the directory itself
            echo "<p> deleting directory $file </p>";
            rmdir($file);
        } else if(is_file($file) and ($file != __FILE__)) {
            // make sure you don't delete the current script
            echo "<p>deleting file $file </p>";
            unlink($file); 
        }
    }
}

если вы хотите удалить все файлы и папки, в которые вы помещаете этот скрипт, назовите его следующим образом

//get current working directory
$dir = getcwd();
unlinkr($dir);

если вы хотите просто удалить только файлы php, назовите его следующим образом

unlinkr($dir, "*.php");

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

unlinkr("/home/user/temp");

Это удалит все файлы в каталоге home / user / temp.

person Tofeeq    schedule 20.11.2015
comment
Старое, но хорошее! Используйте в качестве примера в классе, и это был хит! - person Woody; 14.04.2021

Другое решение: этот класс удаляет все файлы, подкаталоги и файлы в подкаталогах.

class Your_Class_Name {
    /**
     * @see http://php.net/manual/de/function.array-map.php
     * @see http://www.php.net/manual/en/function.rmdir.php 
     * @see http://www.php.net/manual/en/function.glob.php
     * @see http://php.net/manual/de/function.unlink.php
     * @param string $path
     */
    public function delete($path) {
        if (is_dir($path)) {
            array_map(function($value) {
                $this->delete($value);
                rmdir($value);
            },glob($path . '/*', GLOB_ONLYDIR));
            array_map('unlink', glob($path."/*"));
        }
    }
}
person tommy    schedule 17.07.2014

Добавлен универсальный класс обработки файлов и папок для копирования, перемещения, удаления, вычисления размера и т. Д., Который может обрабатывать один файл или набор папок.

https://gist.github.com/4689551

Использовать:

Чтобы скопировать (или переместить) отдельный файл или набор папок / файлов:

$files = new Files();
$results = $files->copyOrMove('source/folder/optional-file', 'target/path', 'target-file-name-for-single-file.only', 'copy');

Удалить один файл или все файлы и папки по пути:

$files = new Files();
$results = $files->delete('source/folder/optional-file.name');

Рассчитайте размер отдельного файла или набора файлов в наборе папок:

$files = new Files();
$results = $files->calculateSize('source/folder/optional-file.name');
person Community    schedule 01.02.2013

Для меня решение с readdir было лучшим и работало отлично. С glob функция не работала в некоторых сценариях.

// Remove a directory recursively
function removeDirectory($dirPath) {
    if (! is_dir($dirPath)) {
        return false;
    }

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

    if ($handle = opendir($dirPath)) {

        while (false !== ($sub = readdir($handle))) {
            if ($sub != "." && $sub != ".." && $sub != "Thumb.db") {
                $file = $dirPath . $sub;

                if (is_dir($file)) {
                    removeDirectory($file);
                } else {
                    unlink($file);
                }
            }
        }

        closedir($handle);
    }

    rmdir($dirPath);
}
person Tiago Silva Pereira    schedule 16.02.2018

Я создал действительно простой пакет под названием Pusheh. С его помощью вы можете очистить каталог или полностью удалить каталог (ссылка Github). Он также доступен на Packagist.

Например, если вы хотите очистить каталог Temp, вы можете сделать:

Pusheh::clearDir("Temp");

// Or you can remove the directory completely
Pusheh::removeDirRecursively("Temp");

Если вам интересно, просмотрите вики.

person MAChitgarha    schedule 25.01.2019
comment
хороший пакет, спасибо - person István Döbrentei; 28.05.2021

Я обновил ответ @Stichoza, чтобы удалить файлы через подпапки.

function glob_recursive($pattern, $flags = 0) {
    $fileList = glob($pattern, $flags);
    foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
        $subPattern = $dir.'/'.basename($pattern);
        $subFileList = glob_recursive($subPattern, $flags);
        $fileList = array_merge($fileList, $subFileList);
    }
    return $fileList;
}

function glob_recursive_unlink($pattern, $flags = 0) {
    array_map('unlink', glob_recursive($pattern, $flags));
}
person tzi    schedule 17.10.2014

Это простой способ и хорошее решение. попробуйте этот код.

array_map('unlink', array_filter((array) array_merge(glob("folder_name/*"))));
person Inventor Bala    schedule 01.06.2021

person    schedule
comment
он должен быть unlink ('/ path / to / directory /'.$ fileInfo- ›getFilename ()); поскольку unlink занимает путь. Но хороший ответ. - person Vic; 04.01.2013
comment
Вы даже можете удалить ссылку ($ fileInfo- ›getPathname ()); что даст вам полный путь к файлу. php.net/manual/en/directoryiterator.getpathname.php - person Josh Holloway; 10.01.2013
comment
Разве DirectoryIterator не выполняет итерацию по подкаталогам? Если это так, в таких случаях будет выдано предупреждение. Разве тело цикла не должно больше выглядеть в ответе Ямико и не проверять каждую запись, является ли это файлом, прежде чем вызывать «unlink»? - person Andreas Linnert; 21.05.2018