Я работаю над функцией PHP, которая рекурсивно удалит все подпапки, которые не содержат файлов, начинающихся с заданного абсолютного пути.
Вот код, разработанный до сих пор:
function RemoveEmptySubFolders($starting_from_path) { // Returns true if the folder contains no files function IsEmptyFolder($folder) { return (count(array_diff(glob($folder.DIRECTORY_SEPARATOR."*"), Array(".", ".."))) == 0); } // Cycles thorugh the subfolders of $from_path and // returns true if at least one empty folder has been removed function DoRemoveEmptyFolders($from_path) { if(IsEmptyFolder($from_path)) { rmdir($from_path); return true; } else { $Dirs = glob($from_path.DIRECTORY_SEPARATOR."*", GLOB_ONLYDIR); $ret = false; foreach($Dirs as $path) { $res = DoRemoveEmptyFolders($path); $ret = $ret ? $ret : $res; } return $ret; } } while (DoRemoveEmptyFolders($starting_from_path)) {} }
По моим испытаниям эта функция работает, хотя я был бы очень рад увидеть любые идеи для лучшего выполнения кода.
Если у вас есть пустая папка в пустой папке в пустой папке, вам нужно будет циклически перебирать ВСЕ папки три раза. Все это, потому что вы сначала выбираете ширину – тестовую папку перед тестированием своих детей. Вместо этого вы должны перейти в дочерние папки перед тестированием, если родительский пуст, таким образом, одного прохода будет достаточно.
function RemoveEmptySubFolders($path) { $empty=true; foreach (glob($path.DIRECTORY_SEPARATOR."*") as $file) { if (is_dir($file)) { if (!RemoveEmptySubFolders($file)) $empty=false; } else { $empty=false; } } if ($empty) rmdir($path); return $empty; }
Кстати, glob не возвращается. и .. записи.
Более короткая версия:
function RemoveEmptySubFolders($path) { $empty=true; foreach (glob($path.DIRECTORY_SEPARATOR."*") as $file) { $empty &= is_dir($file) && RemoveEmptySubFolders($file); } return $empty && rmdir($path); }
Эта строка
$ret = $ret ? $ret : $res;
Можно сделать немного более читаемым:
$ret = $ret || $res;
Или, если PHP имеет побитовый оператор:
$ret |= $res;
Вы можете выполнить команду unix для удаления пустых каталогов.
exec ("find $ start_from_path -type d -empty -exec rmdir {} \; 2> / dev / null");
Это может вызвать проблемы, потому что несколько раз вызовет RemoveEmptySubFolders
, возможно, произнесет ошибки, потому что каждый раз, когда вы вызываете эту функцию, остальные 2 функции определяются снова. Если они уже определены, PHP будет вызывать ошибку, заявив, что функция с тем же именем уже определена.
Вместо этого попробуйте рекурсивно:
function removeEmptySubfolders($path){ if(substr($path,-1)!= DIRECTORY_SEPARATOR){ $path .= DIRECTORY_SEPARATOR; } $d2 = array('.','..'); $dirs = array_diff(glob($path.'*', GLOB_ONLYDIR),$d2); foreach($dirs as $d){ removeEmptySubfolders($d); } if(count(array_diff(glob($path.'*'),$d2))===0){ rmdir($path); } }
Протестировано, работает красиво. Windows 7 PHP 5.3.0 XAMPP
Вы можете попробовать это.
function removeEmptySubfolders($path){ if(substr($path,-1)!= DIRECTORY_SEPARATOR){ $path .= DIRECTORY_SEPARATOR; } $d2 = array('.','..'); $dirs = array_diff(glob($path.'*', GLOB_ONLYDIR),$d2); foreach($dirs as $d){ removeEmptySubfolders($d); } if(count(array_diff(glob($path.'*'),$d2))===0){ $checkEmpSubDir = explode(DIRECTORY_SEPARATOR,$path); for($i=count($checkEmpSubDir)-1;$i>0;$i--){ $path = substr(str_replace($checkEmpSubDir[$i],"",$path),0,-1); if(($files = @scandir($path)) && count($files) <= 2){ rmdir($path); } } } }
Решение для Linux, используя инструмент командной строки, но быстрее и проще, чем с чистым PHP
/** * Remove all empty subdirectories * @param string $dirPath path to base directory * @param bool $deleteBaseDir - Delete also basedir if it is empty */ public static function removeEmptyDirs($dirPath, $deleteBaseDir = false) { if (stristr($dirPath, "'")) { trigger_error('Disallowed character `Single quote` (\') in provided `$dirPath` parameter', E_USER_ERROR); } if (substr($dirPath, -1) != '/') { $dirPath .= '/'; } $modif = $deleteBaseDir ? '' : '*'; exec("find '".$dirPath."'".$modif." -empty -type d -delete", $out); }
Если вам нужна поддержка Windows, используйте константу PHP_OS
и этот однострочный
for /f "delims=" %d in ('dir /s /b /ad ^| sort /r') do rd "%d"`enter code here