Принятый ответ подходит, если вы можете использовать поисковые запросы. Однако существует и другой подход к решению этой проблемы.
Если мы посмотрим на широко предложенное регулярное выражение для этого вопроса:
.*[^a]$
Мы будем что он почти работает. Он не принимает пустую строку, которая может быть немного неудобной. Однако это небольшая проблема при работе с одним персонажем. Однако, если мы хотим исключить целую строку, например. "abc", то:
.*[^a][^b][^c]$
не будет работать. Например, он не принимает ac.
Однако для решения этой проблемы существует простое решение. Мы можем просто сказать:
.{,2}$|.*[^a][^b][^c]$
или более обобщенная версия:
.{,n-1}$|.*[^firstchar][^secondchar]$
где n - длина строки, которую вы хотите запретить (для abc
это 3), а firstchar
, secondchar
, ... являются первыми, вторыми ... n-ыми символами вашей строки (для abc
это будет a
, затем b
, затем c
).
Это происходит из простого наблюдения, что строка, которая короче текста, которую мы не запретим, не может содержать этот текст по определению. Таким образом, мы можем либо принять все, что короче («ab» не «abc»), либо что-то достаточно длинное для нас, но без конца.
Вот пример поиска, который удалит все файлы, которые не являются .jpg:
find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete
В настоящее время доступно как минимум два варианта.
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);
}
$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);
Как насчет этого:
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);
}
Использование 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);
}
Вот простое решение
$dirname = $_POST['d'];
$folder_handler = dir($dirname);
while ($file = $folder_handler->read()) {
if ($file == "." || $file == "..")
continue;
unlink($dirname.'/'.$file);
}
$folder_handler->close();
rmdir($dirname);
Короткая функция, выполняющая задание:
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);
}
Функция 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);
}
?>
Это работает для меня:
function removeDirectory($path) {
$files = glob($path . '/*');
foreach ($files as $file) {
is_dir($file) ? removeDirectory($file) : unlink($file);
}
rmdir($path);
return;
}
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()
Я не помню, откуда я скопировал эту функцию, но похоже, что она не указана, и она работает для меня
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);
}
}
<?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
Работайте со мной отлично
Как видно из большинства проголосовавших комментариев на странице руководства 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);
}
?>
Вы можете использовать файловую систему Symfony ( code ):
// 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);
}
Если вы не уверены, данный путь является каталогом или файлом, вы можете использовать эту функцию для удаления пути
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;
}
}
Что-то вроде этого?
function delete_folder($folder) {
$glob = glob($folder);
foreach ($glob as $g) {
if (!is_dir($g)) {
unlink($g);
} else {
delete_folder("$g/*");
rmdir($g);
}
}
}
Изменение бита Litle кода alcuadrado - glob
не видят файлы с именем из таких точек, как .htaccess
, поэтому я использую scandir и сам скрипт удаляет себя - проверьте __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);
}
Я предпочитаю это, потому что он все еще возвращает 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);
}
Как решение 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!');
}
}
Как насчет этого?
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 );
}
}
Refrence: https://paulund.co.uk/php-delete-directory-and-files-in-directory
Для окон:
system("rmdir ".escapeshellarg($path) . " /s /q");
Независимый от платформы код.
Взял ответ из PHP.net
if(PHP_OS === 'Windows')
{
exec("rd /s /q {$path}");
}
else
{
exec("rm -rf {$path}");
}
Простой и легкий ...
$dir ='pathtodir';
if (is_dir($dir)) {
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
if ($filename->isDir()) continue;
unlink($filename);
}
rmdir($dir);
}
Удалить все файлы в папке array_map('unlink', glob("$directory/*.*"));
Удалить все. * - Файлы в папке (без: «.» и «..») array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
Теперь удалить саму папку rmdir($directory)
Пример для сервера Linux: exec('rm -f -r ' . $cache_folder . '/*');
Лучшее решение для меня
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. ЗАПОМНИТЬ! не пропускайте ПУСТОЙ ЦЕННОСТИ в любой каталог, удаляющий функции !!! (резервируйте их всегда, иначе в один прекрасный день вы можете получить БЕДСТВИЙ !!) [/ g2]
Вот идеальное решение:
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;
}
Обычно я использую это для удаления всех файлов в папке:
array_map('unlink', glob("$dirname/*.*"));
И вы можете сделать
rmdir($dirname);
Это более короткая версия отлично работает для меня
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);
}
}
Я хочу расширить ответ @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);
Какой самый простой способ удалить каталог со всеми его файлами в нем?
blockquote>system("rm -rf ".escapeshellarg($dir));