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

Быстрый способ удаления папки на PHP

В РНР для удаления файла существует функция unlink(), для удаления пустого каталога — rmdir(). Что делать если нужно рекурсивно удалить папку со всеми файлами и подкаталогами. На помощь приходит glob() в связке с array_map().

Заметьте, что в функции нет ни единого цикла.

function removeDir($path) < if (is_file($path)) < @unlink($path); >else < array_map('removeDir',glob('/*')) == @rmdir($path); >@rmdir($path); >
$path = $_SERVER['DOCUMENT_ROOT'].'/test'; removeDir($path);

Русский разработчик со стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Joomla, Drupal. Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги. Веду блог о разработке, дайджест в телеграмме и в ВК. Вы всегда можете нанять меня.

Спасибо за идею, но у меня эта функция не сработала так, как хотелось бы. Я немного подкорректировал функцию и вызов. Теперь она удаляет указанную папку со всеми подпапками и файлами: function removeDir($path) <
return is_file($path)?
@unlink($path):
array_map(‘removeDir’,glob($path.»/*»))==@rmdir($path);
> // Пример вызова
$path = $_SERVER[‘DOCUMENT_ROOT’].’/test’;
removeDir($path);

Не работает. Не удаляет самую верхнюю директорию. Вот рабочий пример
function removeDirectory($dir) if ($objs = glob($dir.»/*»)) foreach($objs as $obj) is_dir($obj) ? removeDirectory($obj) : unlink($obj);
>
>
rmdir($dir);
>

Вы не правы насчет не используются цикла как рас используются вы применяется callback функцию что рекурсивно вызывается на каждое значение массива

Визуально в коде нет ни одного цикла. Код читается проще. О внутреннем устройстве функций РНР речи не идет.

А можете объяснить нубу почему эта функция у меня ругается на фигурные скобки в условии, а если их удалить, то начинает ругаться на собаку?

А, да всё… Я решил проблему — не использую этот скрипт. Всё равно там же используется скрипт создания субдомена через cPanel. Я его немного дописал и он ещё и папки теперь удаляет.

серврере ложится надо что-то полегче
Service Temporarily Unavailable
The server closed the connection without sending any data.
The server is temporarily unable to service your request due to maintenance downtime or capacity problems.
Due to heavy load on the server, connections may be temporarily blocked from locations that fetch an unusually high number of pages.
We apologize for the inconvenience.

Читайте также:  METANIT.COM

wpdiscuz

wpDiscuz

Смотрите также

Категории

  • Программирование (280)
  • WordPress (137)
  • Верстка (109)
  • Браузеры (86)
  • Linux (76)
  • Новости (60)
  • Разное (56)
  • Soft (53)
  • jQuery (29)
  • Проекты (15)
  • Gutenberg (12)
  • Windows (9)
  • Dev Tips (9)
  • Вирус (6)
  • Плагины WordPress (5)
  • PhpStorm Tips (4)
  • Техническое SEO (3)
  • Лучшие плагины 2023 (300)

Каналы в Telegram

Проекты, в которых я принимаю активное участие.

  1. WordPress Digest
    Дайджест новостей из мира WordPress
  2. WordPress Jobs
    Публикуем вакансии и резюме по направлению WordPress
  3. RU WordPress
    WordPress для всех и для каждого. Ссылки, комментарии, приемы, проверенные практикой.
  4. Neural Digest
    Дайджест свежих материалов по нейронным сетям, ChatGPT, OpenAI, Ann, AI
  5. YandexGPT
    Сайт, посвящённый российской нейросети YaGPT/YandexGPT, разработанной компанией Яндекс
  6. Ton Father
    Всё о технологии блокчейн и криптовалютах

Источник

Рекурсивное удаление файлов и директорий на PHP

Рассказываю, как с помощью PHP удалять директории с файлами.

Удалить файл, группу файлов или пустые директории на PHP достаточно просто — для этого есть UnLink и RmDir. Но как быть если нужно удалить не пустые директории с массой файлов и вложенных поддиректорий? Для этого существует рекурсивное удаление.

$dirPath = 'samples/'; 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); >

В PHP 5.2 и выше данную процедуру можно проделать с помощью RecursiveIterator.

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

⚡️ Подписывайся на мой канал @DanilinBiz и ты узнаешь, почему одни фрилансеры пашут, как проклятые, зарабатывая копейки, а другие не напрягаясь поднимают приличные деньги.

Делаю сайты на Вордпресс с 2008 года, в том числе уникальные инструменты для решения сложных бизнес‑задач.

Источник

PHP: Удаление директории

Данная функция рекурсивно удалит саму директорию и её содержимое:

function removeDirectory(string $dir): void < if (is_dir($dir)): chmod($dir, 0777); if ($elements = glob($dir . "/*")): foreach($elements as $element): is_dir($element) ? removeDirectory($element) : unlink($element); endforeach; endif; rmdir($dir); endif; >$dir = __DIR__ . '/dir'; removeDirectory($dir);
function removeDirectory(string $dir): void < if (is_dir($dir)): $elements = array_diff(scandir($dir), ['.','..']); foreach ($elements as $element): is_dir("$dir/$element") ? removeDirectory("$dir/$element") : unlink("$dir/$element"); endforeach; rmdir($dir); endif; >$dir = __DIR__ . '/dir'; removeDirectory($dir);

Удаление только содержимого директории

Данная функция удалит только содержимое директории (очистить её), если не передать в неё вторым параметром флаг на удаление самой директрии.

function clearDir(string $dir, bool $rmdir = false): void < if (is_dir($dir)): if ($objs = glob($dir . '/*')): foreach($objs as $obj): is_dir($obj) ? clearDir($obj, true) : unlink($obj); endforeach; endif; if ($rmdir) rmdir($dir); endif; >$dir = __DIR__ . '/dir'; clearDir($dir); // Очистить директорию и удалить саму директорию clearDir($dir, true);

Удалить файлы из директории, кроме некоторых

Например, нужно удалить все файлы, кроме файла .htaccess . Здесь важно то, что функция работает НЕ рекурсивно и удаляет только файлы:

function removeFilesExcept(string $dir, array $except): void < if (is_dir($dir)): foreach (glob($dir . '/*') as $file): if (!in_array(basename($file), $except) && is_file($file)): unlink($file); endif; endforeach; endif; >$dir = __DIR__ . '/dir'; $except = ['.htaccess']; removeFilesExcept($dir, $except);

Источник

Удаление директории в PHP

Доброго времени суток, дорогие читатели. Сегодня хотелось бы поговорить на тему удаления директории в PHP. Казалось бы, что операция не является сложной, однако некоторые нюансы имеют место быть. Давайте рассмотрим способы, как можно это сделать.

В PHP для этого предусмотрена функция rmdir(). В качестве аргумента она принимает путь до директории, которую Вы хотите удалить. Однако, директория должна быть пустая — это главное условие (если не считать того, что у пользователя, от которого работает веб-сервер, должны быть права на запись для директории). Если в директории будут размещены файлы, то мы получим ошибку при вызове функции. Соответственно, приходим к выводу, что директорию перед использованием функции rmdir() необходимо предварительно очистить.

В сети советуют написать функцию, которой в качестве аргумента будет передаваться путь к директории, которую нам необходимо удалить. В теле функции необходимо организовать листинг содержимого директории, в рамках которого осуществляется проверка — является ли файл директорией. Если файл является директорией, то по данному условию функция вызывает себя. Это необходимо для зачистки вложенных директорий, и это будет работать на всех уровнях вложенности. В ином случае, для файла применяется функция unlink() — она предназначена для удаления файла. За рамками данной проверки на последнем шаге мы удаляем директорию.

Пример реализации:

function recursiveRemoveDir($dir) < $includes = glob($dir.'/*'); foreach ($includes as $include) < if(is_dir($include)) < recursiveRemoveDir($include); >else < unlink($include); >> rmdir($dir); > //Удалим из текущей директории директорию tmp recursiveRemoveDir('tmp'); 

Какие проблемы у данного кода?

В простых случаях директория со всеми вложениями удалится. Но предположим, что в нашей директории присутствует скрытый файл, который начинается с точки, например, .htaccess. Функция glob() представляет из себя glob-подстановку UNIX, в которой по умолчанию не участвуют скрытые файлы (DOTFILES). Например, если мы зайдем в nix-терминал и будем использовать bash, то мы столкнемся с той же проблемой (речь именно о скрытых файлах в рамках glob). Для решения вопроса в bash существует команда shopt -s dotglob — она разрешает glob-подстановку скрытых файлов. В PHP же это можно решить добавлением дополнительно параметра GLOB_BRACE для glob() и расширением паттерна из первого параметра функции.

$includes = glob('tmp/*', GLOB_BRACE);

И тут так же есть проблема — мы столкнемся с бесконечным циклом, так как в массив войдут значения . и .. — что является на системном уровне текущей и родительской директорией. Придем мы к бесконечному циклу (а не к удалению всех родительских директорий), потому что . в рамках сортировки по умолчанию в сформированном массиве будет первее .. — то есть каждый раз мы будет обращаться к одной и той же директории. Для решения проблемы сформируем массив из данных системных директорий и в цикле удалим их индексы из основного массива. Также существует проблема символьных ссылок. Допустим, что в удаляемой директории размещена ссылка на другую директорию, в удалении содержимого которой мы абсолютно не заинтересованы. Для решения проблемы, перед созданием рекурсии, необходимо организовать проверку на то, что сущность не является ссылкой.

В итоге, функция обретает следующий вид:

function recursiveRemoveDir($dir) < $includes = glob($dir.'/*', GLOB_BRACE); $systemDots = preg_grep('/\.+$/', $includes); foreach ($systemDots as $index => $dot) < unset($includes[$index]); >foreach ($includes as $include) < if(is_dir($include) && !is_link($include)) < recursiveRemoveDir($include); >else < unlink($include); >> rmdir($dir); > //Удалим из текущей директории директорию tmp recursiveRemoveDir('tmp'); 

Код рабочий, но на самом деле можно было сделать и проще. В PHP существует класс FilesystemIterator, который уже по умолчанию имеет необходимые нам настройки. В конструктор передается путь до директории, листинг которой нам нужен. Нам достаточно просто создать объект.

function recursiveRemoveDir($dir) < $includes = new FilesystemIterator($dir); foreach ($includes as $include) < if(is_dir($include) && !is_link($include)) < recursiveRemoveDir($include); >else < unlink($include); >> rmdir($dir); > //Удалим из текущей директории директорию tmp recursiveRemoveDir('tmp'); 

В заключение хотелось бы отметить еще один быстрый способ. Корректность его использования весьма сомнительна — отправить команду на выполнение в SHELL.

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

Источник

Оцените статью