¿Eliminar todos los archivos de una carpeta usando PHP?


306

Por ejemplo, tenía una carpeta llamada 'Temp' y quería eliminar o eliminar todos los archivos de esta carpeta usando PHP. ¿Podría hacer esto?


14
Es bueno que esta pregunta se haya respondido a continuación antes de marcarla como duplicada. Las respuestas a continuación son mucho mejores que la pregunta respondida vinculada. Además, la pregunta es diferente, esta pregunta pide vaciar un directorio, no eliminarlo.
Bart Burg

1
Sí, esta es una pregunta diferente que generó diferentes respuestas. No debe marcarse como un duplicado.
Daniel Bingham

Respuestas:


639
$files = glob('path/to/temp/*'); // get all file names
foreach($files as $file){ // iterate files
  if(is_file($file))
    unlink($file); // delete file
}

Si desea eliminar archivos 'ocultos' como .htaccess, debe usar

$files = glob('path/to/temp/{,.}*', GLOB_BRACE);

44
También hay DirectoryIterator o DirectoryRecursiveIterator.
Eugene

66
Aunque es obvio, mencionaría que, por ejemplo, 'ruta / a / temp / *. Txt' eliminará solo los archivos txt y así sucesivamente.
Tertium

¿Esto también funciona para rutas relativas? Entonces, supongamos que la ruta completa es "/ var / www / html / folder_and_files_to_delete /" Y el script de eliminación se coloca en "/var/www/html/delete_folders_and_files.php". ¿Puedo tomar "folder_and_files_to_delete" como ruta?
yoano

1
@yoano sí claro, siempre que la ruta relativa sea correcta.
Floern

¿Está bien usar glob si el directorio tiene decenas de miles o cientos de miles de archivos?
Dave Heq

260

Si desea borrar todo, desde la carpeta (incluyendo subcarpetas) utiliza esta combinación de array_map, unlinky glob:

array_map( 'unlink', array_filter((array) glob("path/to/temp/*") ) );

Esta llamada también puede manejar directorios vacíos (¡gracias por el consejo, @mojuba!)


33
La mejor respuesta, gracias. Para evitar avisos también lo haría glob("...") ?: [](PHP 5.4+) porque para un directorio vacío glob()regresa false.
mojuba

14
Elimina todos los archivos de la carpeta actual, pero devuelve una advertencia para las subcarpetas y no los elimina.
Key-Six

2
Combinando las respuestas de Stichoza y mojuba:array_map('unlink', ( glob( "path/to/temp/*" ) ? glob( "path/to/temp/*" ) : array() ) );
Ewout

77
@Ewout: incluso si combinamos la respuesta de Stichoza y Moujuba cuando su donación devuelve la misma advertencia para las subcarpetas y no las elimina
Sulthan Allaudeen

3
Lamentablemente, esto no elimina subcarpetas.
tmarois

92

Aquí hay un enfoque más moderno usando la Biblioteca PHP Estándar (SPL) .

$dir = "path/to/directory";
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ( $ri as $file ) {
    $file->isDir() ?  rmdir($file) : unlink($file);
}
return true;

1
Esto funciona bien, cuando no tienes acceso SSH y el FTP tarda literalmente horas en eliminar recursivamente muchos archivos y carpetas ... ¡con esas líneas eliminé 35000 archivos en menos de 3 segundos!
guari

Para usuarios de PHP 7.1: $ file-> getRealPath () debe usarse en lugar de $ file. De lo contrario, PHP le dará un error diciendo que unlink requiere una ruta, no una instancia de SplFileInfo.
KeineMaster

68
foreach (new DirectoryIterator('/path/to/directory') as $fileInfo) {
    if(!$fileInfo->isDot()) {
        unlink($fileInfo->getPathname());
    }
}

debe estar desvinculado ('/ ruta / al / directorio /'.$ fileInfo-> getFilename ()); ya que unlink toma el camino. Buena respuesta sin embargo.
Vic

8
Incluso podría hacer unlink ($ fileInfo-> getPathname ()); que le daría la ruta completa al archivo. php.net/manual/en/directoryiterator.getpathname.php
Josh Holloway

¿'DirectoryIterator' no itera también sobre subdirectorios? Si es así, 'desvincular' generaría una advertencia en tales casos. ¿No debería el cuerpo del bucle parecerse más a la respuesta de Yamiko y verificar cada entrada si es un archivo antes de llamar 'desvincular'?
Andreas Linnert

19

Este código de http://php.net/unlink :

/**
 * Delete a file or recursively delete a directory
 *
 * @param string $str Path to file or directory
 */
function recursiveDelete($str) {
    if (is_file($str)) {
        return @unlink($str);
    }
    elseif (is_dir($str)) {
        $scan = glob(rtrim($str,'/').'/*');
        foreach($scan as $index=>$path) {
            recursiveDelete($path);
        }
        return @rmdir($str);
    }
}

16
$dir = 'your/directory/';
foreach(glob($dir.'*.*') as $v){
    unlink($v);
}

11

Ver readdir y desvincular .

<?php
    if ($handle = opendir('/path/to/files'))
    {
        echo "Directory handle: $handle\n";
        echo "Files:\n";

        while (false !== ($file = readdir($handle)))
        {
            if( is_file($file) )
            {
                unlink($file);
            }
        }
        closedir($handle);
    }
?>

10

Asumir que tiene una carpeta con MUCHOS archivos que los lee a todos y luego eliminar en dos pasos no es tan efectivo. Creo que la forma más eficaz de eliminar archivos es usar un comando del sistema.

Por ejemplo, en Linux uso:

exec('rm -f '. $absolutePathToFolder .'*');

O esto si desea la eliminación recursiva sin la necesidad de escribir una función recursiva

exec('rm -f -r '. $absolutePathToFolder .'*');

existen los mismos comandos exactos para cualquier sistema operativo compatible con PHP. Tenga en cuenta que esta es una forma REALIZADA de eliminar archivos. $ absolutePathToFolder DEBE ser verificado y protegido antes de ejecutar este código y se deben otorgar permisos.


2
Poco seguro usando este método, si $absolutePatToFolderalguna vez está vacío
Lawrence Cherone

@LawrenceCherone ¿Hay otras alternativas más seguras?
robsch

3
@LawrenceCherone Espero que nadie ejecute php con permisos de root hoy en día. En serio, espero que la entrada sea "segura", ya que todas las funciones anteriores.
Dario Corno

Las soluciones más votadas no funcionan en entornos de desarrollo donde www o www-data no es el propietario. Depende del administrador del servidor garantizar que se establezcan los derechos adecuados de la carpeta. exec es una herramienta invaluable para hacer cosas, y con gran poder, etc. stackoverflow.com/a/2765171/418974
Christian Bonato

@LawrenceCherone tiene toda la razón, mi respuesta fue para una situación muy específica, solo por razones de rendimiento. Modifiqué mi respuesta de acuerdo a tus notas.
Dario Corno


4

Otra solución: esta clase elimina todos los archivos, subdirectorios y archivos en los subdirectorios.

class Your_Class_Name {
    /**
     * @see http://php.net/manual/de/function.array-map.php
     * @see http://www.php.net/manual/en/function.rmdir.php 
     * @see http://www.php.net/manual/en/function.glob.php
     * @see http://php.net/manual/de/function.unlink.php
     * @param string $path
     */
    public function delete($path) {
        if (is_dir($path)) {
            array_map(function($value) {
                $this->delete($value);
                rmdir($value);
            },glob($path . '/*', GLOB_ONLYDIR));
            array_map('unlink', glob($path."/*"));
        }
    }
}

4

la función unlinkr elimina de forma recursiva todas las carpetas y archivos en la ruta dada al asegurarse de que no elimine el script en sí.

function unlinkr($dir, $pattern = "*") {
    // find all files and folders matching pattern
    $files = glob($dir . "/$pattern"); 

    //interate thorugh the files and folders
    foreach($files as $file){ 
    //if it is a directory then re-call unlinkr function to delete files inside this directory     
        if (is_dir($file) and !in_array($file, array('..', '.')))  {
            echo "<p>opening directory $file </p>";
            unlinkr($file, $pattern);
            //remove the directory itself
            echo "<p> deleting directory $file </p>";
            rmdir($file);
        } else if(is_file($file) and ($file != __FILE__)) {
            // make sure you don't delete the current script
            echo "<p>deleting file $file </p>";
            unlink($file); 
        }
    }
}

si desea eliminar todos los archivos y carpetas donde coloca este script, llámelo de la siguiente manera

//get current working directory
$dir = getcwd();
unlinkr($dir);

si solo desea eliminar solo archivos php, llámelo de la siguiente manera

unlinkr($dir, "*.php");

puedes usar cualquier otra ruta para eliminar los archivos también

unlinkr("/home/user/temp");

Esto eliminará todos los archivos en el directorio home / user / temp.


3

Publicó una clase de manejo de archivos y carpetas de propósito general para copiar, mover, eliminar, calcular tamaño, etc., que puede manejar un solo archivo o un conjunto de carpetas.

https://gist.github.com/4689551

Usar:

Para copiar (o mover) un solo archivo o un conjunto de carpetas / archivos:

$files = new Files();
$results = $files->copyOrMove('source/folder/optional-file', 'target/path', 'target-file-name-for-single-file.only', 'copy');

Eliminar un solo archivo o todos los archivos y carpetas en una ruta:

$files = new Files();
$results = $files->delete('source/folder/optional-file.name');

Calcule el tamaño de un solo archivo o un conjunto de archivos en un conjunto de carpetas:

$files = new Files();
$results = $files->calculateSize('source/folder/optional-file.name');

1
 <?
//delete all files from folder  & sub folders
function listFolderFiles($dir)
{
    $ffs = scandir($dir);
    echo '<ol>';
    foreach ($ffs as $ff) {
        if ($ff != '.' && $ff != '..') {
            if (file_exists("$dir/$ff")) {
                unlink("$dir/$ff");
            }
            echo '<li>' . $ff;
            if (is_dir($dir . '/' . $ff)) {
                listFolderFiles($dir . '/' . $ff);
            }
            echo '</li>';
        }
    }
    echo '</ol>';
}
$arr = array(
    "folder1",
    "folder2"
);
for ($x = 0; $x < count($arr); $x++) {
    $mm = $arr[$x];
    listFolderFiles($mm);
}
//end
?> 

1

Para mí, la solución readdirfue mejor y funcionó de maravilla. Con glob, la función estaba fallando con algunos escenarios.

// Remove a directory recursively
function removeDirectory($dirPath) {
    if (! is_dir($dirPath)) {
        return false;
    }

    if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
        $dirPath .= '/';
    }

    if ($handle = opendir($dirPath)) {

        while (false !== ($sub = readdir($handle))) {
            if ($sub != "." && $sub != ".." && $sub != "Thumb.db") {
                $file = $dirPath . $sub;

                if (is_dir($file)) {
                    removeDirectory($file);
                } else {
                    unlink($file);
                }
            }
        }

        closedir($handle);
    }

    rmdir($dirPath);
}

0

Actualicé la respuesta de @Stichoza para eliminar archivos a través de subcarpetas.

function glob_recursive($pattern, $flags = 0) {
    $fileList = glob($pattern, $flags);
    foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
        $subPattern = $dir.'/'.basename($pattern);
        $subFileList = glob_recursive($subPattern, $flags);
        $fileList = array_merge($fileList, $subFileList);
    }
    return $fileList;
}

function glob_recursive_unlink($pattern, $flags = 0) {
    array_map('unlink', glob_recursive($pattern, $flags));
}

0
public static function recursiveDelete($dir)
{
    foreach (new \DirectoryIterator($dir) as $fileInfo) {
        if (!$fileInfo->isDot()) {
            if ($fileInfo->isDir()) {
                recursiveDelete($fileInfo->getPathname());
            } else {
                unlink($fileInfo->getPathname());
            }
        }
    }
    rmdir($dir);
}

0

Hay un paquete llamado "Pusheh". Al usarlo, puede borrar un directorio o eliminar un directorio por completo ( enlace de Github ). También está disponible en Packagist .

Por ejemplo, si desea borrar el Tempdirectorio, puede hacer:

Pusheh::clearDir("Temp");

// Or you can remove the directory completely
Pusheh::removeDirRecursively("Temp");

Si estás interesado, mira el wiki .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.