Menghapus semua file dari folder menggunakan PHP?

306

Misalnya saya punya folder bernama `Temp 'dan saya ingin menghapus atau menghapus semua file dari folder ini menggunakan PHP. Bisakah saya melakukan ini?

menjauhlah
sumber
14
Untung pertanyaan ini dijawab di bawah sebelum ditandai sebagai duplikat. Jawaban di bawah ini jauh lebih baik daripada pertanyaan yang ditautkan terkait. Ditambah pertanyaannya berbeda, pertanyaan ini meminta untuk mengosongkan direktori, bukan menghapus.
Bart Burg
1
Ya, ini pertanyaan berbeda yang menarik jawaban berbeda. Seharusnya tidak ditandai sebagai duplikat.
Daniel Bingham

Jawaban:

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

Jika Anda ingin menghapus file 'tersembunyi' seperti .htaccess, Anda harus menggunakannya

$files = glob('path/to/temp/{,.}*', GLOB_BRACE);
Floern
sumber
4
Juga ada DirectoryIterator atau DirectoryRecursiveIterator.
Eugene
6
Meskipun sudah jelas, saya akan menyebutkan bahwa, misalnya, 'path / to / temp / *. Txt' hanya akan menghapus file txt dan sebagainya.
Tertium
Apakah ini juga berfungsi untuk jalur relatif? Jadi katakanlah path lengkapnya adalah "/ var / www / html / folder_and_files_to_delete /" Dan skrip penghapusan ditempatkan di "/var/www/html/delete_folders_and_files.php". Bisakah saya mengambil "folder_and_files_to_delete" sebagai path?
yoano
1
@yoano ya tentu, selama jalur relatifnya benar.
Floern
Apakah glob boleh digunakan jika direktori memiliki puluhan ribu atau ratusan ribu file di dalamnya?
Dave Heq
260

Jika Anda ingin menghapus semuanya dari folder (termasuk subfolder) gunakan kombinasi ini array_map, unlinkdan glob:

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

Panggilan ini juga dapat menangani direktori kosong (terima kasih atas tipnya, @mojuba!)

Stichoza
sumber
33
Jawaban terbaik, terima kasih. Untuk menghindari pemberitahuan saya juga akan melakukannya glob("...") ?: [](PHP 5.4+) karena untuk glob()mengembalikan direktori kosongfalse .
mojuba
14
Ini menghapus semua file di folder saat ini, tetapi mengembalikan peringatan untuk subfolder dan tidak menghapusnya.
Kunci-Enam
2
Menggabungkan jawaban Stichoza dan mojuba:array_map('unlink', ( glob( "path/to/temp/*" ) ? glob( "path/to/temp/*" ) : array() ) );
Ewout
7
@Ewout: Sekalipun kita menggabungkan jawaban Stichoza dan Moujuba saat pemberian Anda mengembalikan peringatan yang sama untuk subfolder dan tidak menghapusnya
Sulthan Allaudeen
3
Sayangnya ini tidak menghapus subfolder.
tmarois
92

Berikut ini adalah pendekatan yang lebih modern menggunakan Perpustakaan PHP Standar (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;
Yamiko
sumber
1
Ini bekerja dengan baik, ketika Anda tidak memiliki akses SSH dan FTP membutuhkan waktu berjam - jam untuk menghapus banyak file dan folder secara rekursif ... dengan baris-baris itu saya menghapus 35000 file dalam waktu kurang dari 3 detik!
guari
Untuk pengguna PHP 7.1: $ file-> getRealPath () harus digunakan daripada $ file. Jika tidak, PHP akan memberi Anda kesalahan yang mengatakan bahwa membatalkan tautan memerlukan jalur, bukan turunan dari SplFileInfo.
KeineMaster
68
foreach (new DirectoryIterator('/path/to/directory') as $fileInfo) {
    if(!$fileInfo->isDot()) {
        unlink($fileInfo->getPathname());
    }
}
JakeParis
sumber
itu harus menghapus tautan ('/ path / ke / direktori /'.$ fileInfo-> getFilename ()); karena pembatalan tautan mengambil jalur. Jawaban yang bagus.
Vic
8
Anda bahkan dapat membatalkan tautan ($ fileInfo-> getPathname ()); yang akan memberi Anda path lengkap ke file. php.net/manual/en/directoryiterator.getpathname.php
Josh Holloway
Bukankah 'DirectoryIterator' juga beralih pada subdirektori? Jika demikian, batalkan tautan yang akan menghasilkan peringatan dalam kasus seperti itu. Tidakkah seharusnya badan loop terlihat lebih seperti dalam jawaban Yamiko dan memeriksa setiap entri apakah itu file sebelum memanggil 'putuskan tautan'?
Andreas Linnert
19

Kode ini dari 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);
    }
}
Poelinca Dorin
sumber
16
$dir = 'your/directory/';
foreach(glob($dir.'*.*') as $v){
    unlink($v);
}
Haim Evgi
sumber
11

Lihat readdir dan putuskan tautan .

<?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);
    }
?>
StampedeXV
sumber
10

Dengan asumsi Anda memiliki folder dengan BANYAK file membaca semuanya dan kemudian menghapus dalam dua langkah tidak berkinerja baik. Saya percaya cara paling berkinerja untuk menghapus file adalah dengan hanya menggunakan perintah sistem.

Sebagai contoh di linux saya menggunakan:

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

Atau ini jika Anda ingin penghapusan rekursif tanpa perlu menulis fungsi rekursif

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

perintah persis yang sama ada untuk OS apa pun yang didukung oleh PHP. Ingatlah ini adalah cara PERFORMING menghapus file. $ absolutePathToFolder HARUS diperiksa dan diamankan sebelum menjalankan kode ini dan izin harus diberikan.

Dario Corno
sumber
2
Agak tidak aman menggunakan metode ini, jika $absolutePatToFolderpernah kosong
Lawrence Cherone
@LawrenceCherone Apakah alternatif lain lebih aman?
robsch
3
@LawrenceCherone Saya harap tidak ada yang menjalankan php dengan izin root saat ini. Menjadi serius, saya berharap input menjadi "aman", karena semua fungsi di atas.
Dario Corno
Solusi yang paling banyak dipilih tidak bekerja di lingkungan pengembang yang tidak memiliki pemilik atau www-data. Terserah admin server untuk memastikan hak folder tersebut diatur dengan benar. exec adalah alat yang sangat berharga untuk menyelesaikan sesuatu, dan dengan kekuatan besar, dll. stackoverflow.com/a/2765171/418974
Christian Bonato
@LawrenceCherone Anda benar-benar benar jawaban saya dimaksudkan untuk situasi yang sangat spesifik, hanya untuk alasan kinerja Dimodifikasi jawaban saya sesuai dengan catatan Anda.
Dario Corno
4

Solusi lain: Kelas ini menghapus semua file, subdirektori dan file di sub direktori.

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."/*"));
        }
    }
}
tommy
sumber
4

fungsi unlinkr menghapus semua folder dan file di jalur yang diberikan secara rekursif dengan memastikan tidak menghapus skrip itu sendiri.

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

jika Anda ingin menghapus semua file dan folder tempat Anda menempatkan skrip ini, panggil sebagai berikut

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

jika Anda hanya ingin menghapus hanya file php lalu panggil sebagai berikut

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

Anda dapat menggunakan jalur lain untuk menghapus file juga

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

Ini akan menghapus semua file di direktori home / user / temp.

Tofik
sumber
3

Diposting file tujuan umum dan kelas penanganan folder untuk menyalin, memindahkan, menghapus, menghitung ukuran, dll., Yang dapat menangani satu file atau satu set folder.

https://gist.github.com/4689551

Menggunakan:

Untuk menyalin (atau memindahkan) satu file atau satu set folder / file:

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

Hapus satu file atau semua file dan folder di jalur:

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

Hitung ukuran satu file atau satu set file dalam satu set folder:

$files = new Files();
$results = $files->calculateSize('source/folder/optional-file.name');
AmyStephen
sumber
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
?> 
pengguna5579724
sumber
1

Bagi saya, solusi dengan readdiryang terbaik dan bekerja seperti pesona. Dengan glob, fungsi gagal dengan beberapa skenario.

// 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);
}
Tiago Silva Pereira
sumber
0

Saya memperbarui jawaban @Stichoza untuk menghapus file melalui subfolder.

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));
}
tzi
sumber
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);
}
Mehmet
sumber
0

Ada paket yang disebut "Pusheh". Dengan menggunakannya, Anda dapat menghapus direktori atau menghapus direktori sepenuhnya ( tautan Github ). Ini tersedia di Packagist , juga.

Misalnya, jika Anda ingin menghapus Tempdirektori, Anda dapat melakukan:

Pusheh::clearDir("Temp");

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

Jika Anda tertarik, lihat wiki .

MAChitgarha
sumber