php - recursivo - ¿Eliminar directorio con archivos en él?
eliminar carpeta ubuntu root (30)
Me pregunto, ¿cuál es la forma más fácil de eliminar un directorio con todos sus archivos?
Estoy usando rmdir(PATH . ''/'' . $value);
para eliminar una carpeta, sin embargo, si hay archivos dentro de ella, simplemente no puedo eliminarla.
¿Cuál es la forma más fácil de eliminar un directorio con todos sus archivos?
system("rm -rf ".escapeshellarg($dir));
¿Algo como esto?
function delete_folder($folder) {
$glob = glob($folder);
foreach ($glob as $g) {
if (!is_dir($g)) {
unlink($g);
} else {
delete_folder("$g/*");
rmdir($g);
}
}
}
¿Qué pasa con esto?
function recursiveDelete($dirPath, $deleteParent = true){
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
$path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname());
}
if($deleteParent) rmdir($dirPath);
}
2 centavos para agregar a ESTA respuesta anterior, lo cual es genial por cierto
Después de que su función global (o similar) haya escaneado / leído el directorio, agregue un condicional para verificar que la respuesta no esté vacía, o se arrojará un invalid argument supplied for foreach()
advertencia invalid argument supplied for foreach()
. Asi que...
if( ! empty( $files ) )
{
foreach( $files as $file )
{
// do your stuff here...
}
}
Mi función completa (como método de objeto):
private function recursiveRemoveDirectory( $directory )
{
if( ! is_dir( $directory ) )
{
throw new InvalidArgumentException( "$directory must be a directory" );
}
if( substr( $directory, strlen( $directory ) - 1, 1 ) != ''/'' )
{
$directory .= ''/'';
}
$files = glob( $directory . "*" );
if( ! empty( $files ) )
{
foreach( $files as $file )
{
if( is_dir( $file ) )
{
$this->recursiveRemoveDirectory( $file );
}
else
{
unlink( $file );
}
}
}
rmdir( $directory );
} // END recursiveRemoveDirectory()
Aquí está la solución que funciona a la perfección:
function unlink_r($from) {
if (!file_exists($from)) {return false;}
$dir = opendir($from);
while (false !== ($file = readdir($dir))) {
if ($file == ''.'' OR $file == ''..'') {continue;}
if (is_dir($from . DIRECTORY_SEPARATOR . $file)) {
unlink_r($from . DIRECTORY_SEPARATOR . $file);
}
else {
unlink($from . DIRECTORY_SEPARATOR . $file);
}
}
rmdir($from);
closedir($dir);
return true;
}
Aquí hay una solución simple.
$dirname = $_POST[''d''];
$folder_handler = dir($dirname);
while ($file = $folder_handler->read()) {
if ($file == "." || $file == "..")
continue;
unlink($dirname.''/''.$file);
}
$folder_handler->close();
rmdir($dirname);
Aquí tiene una recursión agradable y simple para eliminar todos los archivos en el directorio de origen, incluido ese directorio:
function delete_dir($src) {
$dir = opendir($src);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != ''.'' ) && ( $file != ''..'' )) {
if ( is_dir($src . ''/'' . $file) ) {
delete_dir($src . ''/'' . $file);
}
else {
unlink($src . ''/'' . $file);
}
}
}
closedir($dir);
rmdir($src);
}
La función se basa en la recursión hecha para copiar el directorio. Puede encontrar esa función aquí: Copie todo el contenido de un directorio a otro usando php
Como la solución de Playnox, pero con el elegante DirectoryIterator incorporado:
function delete_directory($dirPath){
if(is_dir($dirPath)){
$objects=new DirectoryIterator($dirPath);
foreach ($objects as $object){
if(!$object->isDot()){
if($object->isDir()){
delete_directory($object->getPathname());
}else{
unlink($object->getPathname());
}
}
}
rmdir($dirPath);
}else{
throw new Exception(__FUNCTION__.''(dirPath): dirPath is not a directory!'');
}
}
Como se ve en el comentario más votado en la página del manual de PHP sobre rmdir()
(consulte http://php.net/manual/es/function.rmdir.php ), la función glob()
no devuelve archivos ocultos. scandir()
se proporciona como una alternativa que resuelve ese problema.
El algoritmo descrito allí (que funcionó como un encanto en mi caso) es:
<?php
function delTree($dir)
{
$files = array_diff(scandir($dir), array(''.'', ''..''));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
?>
Ejemplo para el servidor Linux: exec(''rm -f -r '' . $cache_folder . ''/*'');
Eliminar todos los archivos en la carpeta
array_map(''unlink'', glob("$directory/*.*"));
Eliminar todos. * - Archivos en la carpeta (sin: "." Y "..")
array_map(''unlink'', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
Ahora borra la carpeta
rmdir($directory)
Esta es una versión más corta que funciona muy bien para mí.
function deleteDirectory($dirPath) {
if (is_dir($dirPath)) {
$objects = scandir($dirPath);
foreach ($objects as $object) {
if ($object != "." && $object !="..") {
if (filetype($dirPath . DIRECTORY_SEPARATOR . $object) == "dir") {
deleteDirectory($dirPath . DIRECTORY_SEPARATOR . $object);
} else {
unlink($dirPath . DIRECTORY_SEPARATOR . $object);
}
}
}
reset($objects);
rmdir($dirPath);
}
}
Esta funciona para mí:
function removeDirectory($path) {
$files = glob($path . ''/*'');
foreach ($files as $file) {
is_dir($file) ? removeDirectory($file) : unlink($file);
}
rmdir($path);
return;
}
Función corta que hace el trabajo:
function deleteDir($path) {
return is_file($path) ?
@unlink($path) :
array_map(__FUNCTION__, glob($path.''/*'')) == @rmdir($path);
}
Lo uso en una clase de Utils como esta:
class Utils {
public static function deleteDir($path) {
$class_func = array(__CLASS__, __FUNCTION__);
return is_file($path) ?
@unlink($path) :
array_map($class_func, glob($path.''/*'')) == @rmdir($path);
}
}
Con gran poder viene una gran responsabilidad : cuando llama a esta función con un valor vacío, eliminará los archivos que comienzan en la raíz ( /
). Como salvaguarda puedes verificar si la ruta está vacía:
function deleteDir($path) {
if (empty($path)) {
return false;
}
return is_file($path) ?
@unlink($path) :
array_map(__FUNCTION__, glob($path.''/*'')) == @rmdir($path);
}
Generalmente lo uso para borrar todos los archivos en una carpeta:
array_map(''unlink'', glob("$dirname/*.*"));
Y luego puedes hacer
rmdir($dirname);
Hay al menos dos opciones disponibles en la actualidad.
Antes de eliminar la carpeta, elimine todos sus archivos y carpetas (¡y esto significa recursión!). Aquí hay un ejemplo:
public static function deleteDir($dirPath) { if (! is_dir($dirPath)) { throw new InvalidArgumentException("$dirPath must be a directory"); } if (substr($dirPath, strlen($dirPath) - 1, 1) != ''/'') { $dirPath .= ''/''; } $files = glob($dirPath . ''*'', GLOB_MARK); foreach ($files as $file) { if (is_dir($file)) { self::deleteDir($file); } else { unlink($file); } } rmdir($dirPath); }
Y si está utilizando 5.2+, puede usar un RecursiveIterator para hacerlo sin necesidad de hacer la recursión usted mismo:
$dir = ''samples'' . DIRECTORY_SEPARATOR . ''sampledirtree''; $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS); $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); foreach($files as $file) { if ($file->isDir()){ rmdir($file->getRealPath()); } else { unlink($file->getRealPath()); } } rmdir($dir);
La función Glob no devuelve los archivos ocultos, por lo tanto, scandir puede ser más útil cuando se intenta eliminar recursivamente un árbol.
<?php
public static function delTree($dir) {
$files = array_diff(scandir($dir), array(''.'',''..''));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
?>
La mejor solucion para mi
my_folder_delete("../path/folder");
código:
function my_folder_delete($path) {
if(!empty($path) && is_dir($path) ){
$dir = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs are not included,otherwise DISASTER HAPPENS :)
$files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($files as $f) {if (is_file($f)) {unlink($f);} else {$empty_dirs[] = $f;} } if (!empty($empty_dirs)) {foreach ($empty_dirs as $eachDir) {rmdir($eachDir);}} rmdir($path);
}
}
ps recuerde!
No pase VALORES VACÍOS a ninguna función de eliminación de directorios! (haz una copia de seguridad de ellos siempre, de lo contrario, un día podrías tener DESASTRE!)
No recuerdo de dónde copié esta función, pero parece que no está en la lista y está funcionando para mí.
function rm_rf($path) {
if (@is_dir($path) && is_writable($path)) {
$dp = opendir($path);
while ($ent = readdir($dp)) {
if ($ent == ''.'' || $ent == ''..'') {
continue;
}
$file = $path . DIRECTORY_SEPARATOR . $ent;
if (@is_dir($file)) {
rm_rf($file);
} elseif (is_writable($file)) {
unlink($file);
} else {
echo $file . "is not writable and cannot be removed. Please fix the permission or select a new path./n";
}
}
closedir($dp);
return rmdir($path);
} else {
return @unlink($path);
}
}
Para ventanas:
system("rmdir ".escapeshellarg($path) . " /s /q");
Prefiero esto porque sigue siendo VERDADERO cuando tiene éxito y FALSO cuando falla, y también evita un error en el que una ruta vacía podría intentar eliminar todo de ''/ *'' !!
function deleteDir($path)
{
return !empty($path) && is_file($path) ?
@unlink($path) :
(array_reduce(glob($path.''/*''), function ($r, $i) { return $r && deleteDir($i); }, TRUE)) && @rmdir($path);
}
Puedes intentarlo de la siguiente manera:
/*
* Remove the directory and its content (all files and subdirectories).
* @param string $dir the directory name
*/
function rmrf($dir) {
foreach (glob($dir) as $file) {
if (is_dir($file)) {
rmrf("$file/*");
rmdir($file);
} else {
unlink($file);
}
}
}
Puedes usar el Filesystem de Filesystem de Symfony ( code ):
// composer require symfony/filesystem
use Symfony/Component/Filesystem/Filesystem;
(new Filesystem)->remove($dir);
Sin embargo, no pude eliminar algunas estructuras de directorios complejas con este método, por lo que primero debe intentarlo para asegurarse de que funciona correctamente.
Podría eliminar dicha estructura de directorios utilizando una implementación específica de Windows:
$dir = strtr($dir, ''/'', ''//');
// quotes are important, otherwise one could
// delete "foo" instead of "foo bar"
system(''RMDIR /S /Q "''.$dir.''"'');
Y solo para completar, aquí hay un viejo código mío:
function xrmdir($dir) {
$items = scandir($dir);
foreach ($items as $item) {
if ($item === ''.'' || $item === ''..'') {
continue;
}
$path = $dir.''/''.$item;
if (is_dir($path)) {
xrmdir($path);
} else {
unlink($path);
}
}
rmdir($dir);
}
Que hay de esto
function Delete_Directory($Dir)
{
if(is_dir($Dir))
{
$files = glob( $Dir . ''*'', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file )
{
Delete_Directory( $file );
}
if(file_exists($Dir))
{
rmdir($Dir);
}
}
elseif(is_file($Dir))
{
unlink( $Dir );
}
}
Refrence: https://paulund.co.uk/php-delete-directory-and-files-in-directory
Quiero ampliar la respuesta de @alcuadrado con el comentario de @Vijit para manejar los enlaces simbólicos. En primer lugar, utilice getRealPath (). Pero luego, si tiene algún enlace simbólico que sea una carpeta, fallará, ya que intentará llamar a rmdir en un enlace, por lo que necesita una verificación adicional.
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
if ($file->isLink()) {
unlink($file->getPathname());
} else if ($file->isDir()){
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
rmdir($dir);
Se modificó un poco el código de alcuadrado - glob
no ve archivos con nombre de puntos como .htaccess
así que uso scandir y el script se borra solo - verifique __FILE__
.
function deleteDir($dirPath) {
if (!is_dir($dirPath)) {
throw new InvalidArgumentException("$dirPath must be a directory");
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != ''/'') {
$dirPath .= ''/'';
}
$files = scandir($dirPath);
foreach ($files as $file) {
if ($file === ''.'' || $file === ''..'') continue;
if (is_dir($dirPath.$file)) {
deleteDir($dirPath.$file);
} else {
if ($dirPath.$file !== __FILE__) {
unlink($dirPath.$file);
}
}
}
rmdir($dirPath);
}
Si no está seguro, la ruta dada es el directorio o el archivo, entonces puede usar esta función para eliminar la ruta
function deletePath($path) {
if(is_file($path)){
unlink($path);
} elseif(is_dir($path)){
$path = (substr($path, -1) !== DIRECTORY_SEPARATOR) ? $path . DIRECTORY_SEPARATOR : $path;
$files = glob($path . ''*'');
foreach ($files as $file) {
deleteDirPath($file);
}
rmdir($path);
} else {
return false;
}
}
Simple y fácil...
$dir =''pathtodir'';
if (is_dir($dir)) {
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
if ($filename->isDir()) continue;
unlink($filename);
}
rmdir($dir);
}
Usando DirectoryIterator un equivalente de una respuesta anterior ...
function deleteFolder($rootPath)
{
foreach(new DirectoryIterator($rootPath) as $fileToDelete)
{
if($fileToDelete->isDot()) continue;
if ($fileToDelete->isFile())
unlink($fileToDelete->getPathName());
if ($fileToDelete->isDir())
deleteFolder($fileToDelete->getPathName());
}
rmdir($rootPath);
}
<?php
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);
}
}
?>
Haz probado el código obove de php.net
Trabaja para mi bien