recursivo - recursividad con php
¿Una función de directorio de eliminación recursiva para PHP? (7)
Estoy usando PHP para mover los contenidos de una subcarpeta de imágenes
GalleryName / images /
en otra carpeta. Después de la mudanza, necesito eliminar el directorio GalleryName y todo lo demás dentro de él .
Sé que rmdir()
no funcionará a menos que el directorio esté vacío. He pasado un tiempo tratando de construir una función recursiva para scandir()
comenzando desde la parte superior y luego unlink()
si es un archivo y scandir()
si es un directorio, luego rmdir()
cada directorio vacío como yo voy.
Hasta el momento 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 estoy interesado en saber si alguno de ustedes recomienda aquí una sobre otras.
¿Qué hay de este problema?
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);
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);
}
Hay otro hilo con más ejemplos aquí: ¿Cómo puedo eliminar recursivamente un directorio y todo su contenido (archivos + subdirectorios) en PHP?
Si usa Yii, puede dejarlo en el marco:
CFileHelper::removeDirectory($my_directory);
He adaptado una función que maneja archivos Unix ocultos con el prefijo de punto y usa glob:
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);
}
Prefiero un método enriquecido derivado de las páginas de ayuda php 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 por mi decisión:
- menos código
- velocidad
- mantenlo simple
Si el servidor de la aplicación ejecuta Linux, simplemente use la función shell_exec () y proporcione el comando rm -R, como este:
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
elimina un archivo o directorio pasado en $dir_path
y la opción -R
le dice al sistema que lo ejecute recursivamente.
public static function rrmdir($dir)
{
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file) {
if ($file != "." && $file != "..") {
if (filetype($dir . "/" . $file) == "dir")
self::rrmdir($dir . "/" . $file);
else
unlink($dir . "/" . $file);
}
}
reset($files);
rmdir($dir);
}
}