php - una - ¿Cómo elimino un directorio que no está vacío?
eliminar todo el contenido de una carpeta c# (8)
Estoy intentando eliminar un directorio con rmdir
, pero recibí el mensaje ''Directorio no vacío'' porque todavía tiene archivos.
¿Qué función puedo usar para eliminar un directorio con todos los archivos?
Aquí lo que utilicé:
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);
Con esta función, podrás eliminar cualquier archivo o carpeta
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);
}
Mi caso tenía bastantes directorios complicados (nombres que contienen caracteres especiales, anidamiento profundo, etc.) y archivos ocultos que producían errores de "Directorio no vacío" con otras soluciones sugeridas. Como una solución solo para Unix era inaceptable, la probé hasta que llegué a la siguiente solución (que funcionó bien en mi caso):
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;
}
No hay una función incorporada para hacer esto, pero vea los comentarios en la parte inferior de http://us3.php.net/rmdir . Varios comentaristas publicaron sus propias funciones recursivas de eliminación de directorios. Usted puede elegir entre ellos.
Aquí hay uno que parece decente :
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);
}
Editar: solo podría invocar rm -rf
si quiere mantener las cosas simples. Eso hace que tu script solo sea UNIX, así que ten cuidado con eso. Si sigues esa ruta, intentaré algo como:
function deleteDirectory($dir) {
system(''rm -rf '' . escapeshellarg($dir), $retval);
return $retval == 0; // UNIX commands return zero on success
}
No se puede pensar en una manera más fácil y más eficiente de hacer eso que esto
<?php
$dirname = ''./myfolder'';
if (is_dir($dirname)) {
$dir = new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS);
foreach (new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST ) as $filename => $file) {
if (is_file($filename))
unlink($filename);
else
rmdir($filename);
}
rmdir($dirname); // Now remove myfolder
}
?>
Pruebe la siguiente función práctica:
/**
* 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);
}
Siempre puedes intentar usar los comandos del sistema.
Si está en uso de Linux: rm -rf /dir
Si usa Windows: rd c:/dir /S /Q
En el post anterior ( John Kugelman ), supongo que el analizador de PHP optimizará ese scandir en el foreach, pero me parece incorrecto tener el scandir
en la declaración de condición foreach
.
También puede hacer dos comandos array_shift
para eliminar el .
y ..
lugar de verificar siempre el ciclo.
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);
}
}