2009-10-31 37 views
34

Estoy intentando eliminar un directorio con rmdir, pero recibí el mensaje 'Directorio no vacío', porque todavía tiene archivos.¿Cómo elimino un directorio que no está vacío?

¿Qué función puedo usar para eliminar un directorio con todos los archivos?

+0

duplicados posibles de [¿Cómo recursiva eliminar un directorio y todo su contenido (archivos + subdirectorios) en PHP?] (http://stackoverflow.com/questions/3338123/how-do-i-recursively-delete-a-directory-and-its-entire-contents-files-sub-dir) – MaxiWheat

Respuesta

78

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í es one that looks decent:

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: Sólo 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 vas por esa ruta, intentaré algo como:

function deleteDirectory($dir) { 
    system('rm -rf ' . escapeshellarg($dir), $retval); 
    return $retval == 0; // UNIX commands return zero on success 
} 
+8

Cuando se trata de PHP, ** siempre ** verifique el manual en línea y los comentarios. En general, se garantiza que alguien tuvo el problema primero y lo comentó allí. –

+0

Escogí este: $ path = "/ path/to/empty"; $ cmd = "rm -rf $ ruta"; '$ cmd'; Hay algo malo con eso? – zeckdude

+2

+1 para escapeshellarg() para seguridad – namespaceform

5

Siempre puedes tratar de usar los comandos del sistema.

Si en el uso de Linux: rm -rf /dir Si en las ventanas usar: rd c:\dir /S /Q

En el post anterior (John Kugelman) supongo que puede interpretar optimizará que scandir en el foreach pero sólo parece mal a mí tener la scandir en la declaración de condición foreach.
También puede hacer dos mandatos array_shift para eliminar . y .. en lugar de comprobar siempre el ciclo.

2
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); 
    } 
} 
1

Aquí lo que he utilizado:

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); 
0

intente lo 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); 
} 
0

Con esta función, usted será capaz de 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); 
} 
1

Mi caso tenía bastantes directorios complicados (na con caracteres especiales, anidamiento profundo, etc.) y archivos ocultos que produjeron errores de "Directorio no vacío" con otras soluciones sugeridas. Puesto que un Unix única solución era inaceptable, he probado hasta que llegué a la siguiente solución (que funcionaba 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; 
} 
+0

Para ampliar la necesidad de preg_replace, era necesario porque algunos directorios (con caracteres especiales) omitirían subdirectorios que claramente existían. Encontré la nota preg_replace de un comentario en el php.documentación de red para glob(), donde alguien más luchó durante horas con el mismo problema. –

+0

Este es el único que podría resolver mi problema también +1, gracias – Franco

Cuestiones relacionadas