Próbuję usunąć katalog z rmdir
, ale otrzymałem komunikat "Directory not empty", ponieważ nadal ma w nim pliki.Jak usunąć katalog, który nie jest pusty?
Jaką funkcję mogę użyć do usunięcia katalogu zawierającego wszystkie pliki w nim zawarte?
Próbuję usunąć katalog z rmdir
, ale otrzymałem komunikat "Directory not empty", ponieważ nadal ma w nim pliki.Jak usunąć katalog, który nie jest pusty?
Jaką funkcję mogę użyć do usunięcia katalogu zawierającego wszystkie pliki w nim zawarte?
Nie ma wbudowanej funkcji, aby to zrobić, ale zobacz komentarze na dole: http://us3.php.net/rmdir. Wielu komentujących opublikowało własne funkcje kasowania katalogów rekursywnych. Możesz wybrać z nich.
function deleteDirectory($dir) {
if (!file_exists($dir)) {
return true;
}
if (!is_dir($dir)) {
return unlink($dir);
}
foreach (scandir($dir) as $item) {
if ($item == '.' || $item == '..') {
continue;
}
if (!deleteDirectory($dir . DIRECTORY_SEPARATOR . $item)) {
return false;
}
}
return rmdir($dir);
}
Edit: Można po prostu powołać rm -rf
jeśli chcesz zachować rzeczy proste. To sprawia, że twój skrypt jest uniksowy, więc strzeż się tego. Jeśli wybierzesz tę trasę, wypróbuję coś takiego:
function deleteDirectory($dir) {
system('rm -rf ' . escapeshellarg($dir), $retval);
return $retval == 0; // UNIX commands return zero on success
}
Jeśli chodzi o PHP, ** zawsze ** sprawdź podręcznik online i komentarze. Generalnie gwarantuje to, że ktoś miał problem pierwszy i skomentował. –
Wybrałem ten: $ path = "/ path/to/empty"; $ cmd = "rm -rf $ path"; '$ cmd'; Czy coś jest z tym nie tak? – zeckdude
+1 dla escapeshellarg() dla bezpieczeństwa – namespaceform
Zawsze możesz spróbować użyć poleceń systemowych.
Jeżeli na użytkowania Linux: rm -rf /dir
Jeśli na oknach użyć: rd c:\dir /S /Q
W poście powyżej (John Kugelman) Przypuszczam, że parser PHP zoptymalizuje że scandir w foreach ale po prostu wydaje się źle mi się mieć scandir
w oświadczeniu o warunku foreach
.
Można również wykonać dwie komendy array_shift
, aby usunąć .
i ..
zamiast zawsze sprawdzać w pętli.
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);
}
}
Oto co kiedyś:
function emptyDir($dir) {
if (is_dir($dir)) {
$scn = scandir($dir);
foreach ($scn as $files) {
if ($files !== '.') {
if ($files !== '..') {
if (!is_dir($dir . '/' . $files)) {
unlink($dir . '/' . $files);
} else {
emptyDir($dir . '/' . $files);
rmdir($dir . '/' . $files);
}
}
}
}
}
}
$dir = 'link/to/your/dir';
emptyDir($dir);
rmdir($dir);
Spróbuj następującą poręczną funkcję:
/**
* Removes directory and its contents
*
* @param string $path Path to the directory.
*/
function _delete_dir($path) {
if (!is_dir($path)) {
throw new InvalidArgumentException("$path must be a directory");
}
if (substr($path, strlen($path) - 1, 1) != DIRECTORY_SEPARATOR) {
$path .= DIRECTORY_SEPARATOR;
}
$files = glob($path . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
_delete_dir($file);
} else {
unlink($file);
}
}
rmdir($path);
}
Dzięki tej funkcji, będzie można usunąć dowolny plik lub folder
function deleteDir($dirPath)
{
if (!is_dir($dirPath)) {
if (file_exists($dirPath) !== false) {
unlink($dirPath);
}
return;
}
if ($dirPath[strlen($dirPath) - 1] != '/') {
$dirPath .= '/';
}
$files = glob($dirPath . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
deleteDir($file);
} else {
unlink($file);
}
}
rmdir($dirPath);
}
Mój przypadek miał sporo trudnych katalogów (na mes zawierający znaki specjalne, zagnieżdżanie głębokie, itp.) oraz ukryte pliki, które powodowały błędy "Directory not empty" z innymi sugerowanymi rozwiązaniami. Ponieważ Unix Jedynym rozwiązaniem było nie do przyjęcia, testowałem aż dotarłem na następujące rozwiązanie (które sprawdziły się w moim przypadku):
function removeDirectory($path) {
// The preg_replace is necessary in order to traverse certain types of folder paths (such as /dir/[[dir2]]/dir3.abc#/)
// The {,.}* with GLOB_BRACE is necessary to pull all hidden files (have to remove or get "Directory not empty" errors)
$files = glob(preg_replace('/(\*|\?|\[)/', '[$1]', $path).'/{,.}*', GLOB_BRACE);
foreach ($files as $file) {
if ($file == $path.'/.' || $file == $path.'/..') { continue; } // skip special dir entries
is_dir($file) ? removeDirectory($file) : unlink($file);
}
rmdir($path);
return;
}
Aby rozszerzyć zapotrzebowanie na preg_replace, było to konieczne, ponieważ niektóre katalogi (ze znakami specjalnymi) pomijałyby podkatalogi, które wyraźnie istniały. Znalazłem notatkę preg_replace z komentarza w php.net dokumentacji dla glob(), gdzie ktoś inny walczył godzinami z tym samym problemem. –
Jest to jedyny, który może rozwiązać mój problem również +1, dzięki – Franco
Możliwy duplikat [Jak mogę rekursywnie usunąć katalog i całą jego zawartość (pliki + sub dirs) w PHP?] (http://stackoverflow.com/questions/3338123/how-do-i-recursively-delete-a-directory-and-its-entire-contents-files-sub-dir) – MaxiWheat