PHP kullanarak bir klasördeki tüm dosyalar silinsin mi?


306

Örneğin, `` Temp '' adlı bir klasörüm vardı ve PHP kullanarak bu klasördeki tüm dosyaları silmek veya silmek istedim. Bunu yapabilir miyim?


14
Bu sorunun yinelenen olarak işaretlenmeden önce cevaplanması iyi bir şey. Aşağıdaki cevaplar, bağlantılı cevaplı sorudan çok daha iyidir. Artı soru farklı, bu soru bir dizini boşaltmak istiyor, silmek değil.
Bart Burg

1
Evet, bu farklı cevaplar veren farklı bir soru. Yinelenen olarak işaretlenmemelidir.
Daniel Bingham

Yanıtlar:


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

.Htaccess gibi 'gizli' dosyaları kaldırmak istiyorsanız,

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

4
Ayrıca DirectoryIterator veya DirectoryRecursiveIterator vardır.
Eugene

6
Her ne kadar açık olsa da, örneğin, '/ / temp / * .txt yolunun' sadece txt dosyalarını kaldıracağını söyleyebilirim.
Tertium

Bu göreli yollar için de geçerli mi? Diyelim ki tam yol "/ var / www / html / folder_and_files_to_delete /" Ve silme komut dosyası "/var/www/html/delete_folders_and_files.php" içine yerleştirilmiş. Sadece "folder_and_files_to_delete" yolunu alabilir miyim?
yoano

1
@yoano evet emin, göreli yol doğru olduğu sürece.
Floern

Eğer dizinde on binlerce veya yüz binlerce dosya varsa glob kullanmak uygun mudur?
Dave Heq

260

Eğer bu arada kullanın (alt klasörler dahil) klasöründen her şeyi silmek istiyorsanız array_map, unlinkve glob:

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

Bu çağrı boş dizinleri de işleyebilir (ipucu için teşekkürler, @mojuba!)


33
En iyi cevap, teşekkürler. Bildirimlerden kaçınmak için de yapardım glob("...") ?: [](PHP 5.4+) çünkü boş bir dizin için glob()geri döner false.
mojuba

14
Geçerli klasördeki tüm dosyaları siler, ancak alt klasörler için bir uyarı döndürür ve bunları silmez.
Key-Six

2
Stichoza ve mojuba cevaplarını birleştiren:array_map('unlink', ( glob( "path/to/temp/*" ) ? glob( "path/to/temp/*" ) : array() ) );
Ewout

7
@Ewout: Verdiğiniz gibi Stichoza'nın ve Moujuba'nın cevabını birleştirsek bile, alt klasörler için aynı uyarıyı döndürür ve bunları silmez
Sulthan Allaudeen

3
Ne yazık ki bu alt klasörleri silmez.
tmarois

92

İşte Standart PHP Kütüphanesi'ni (SPL) kullanarak daha modern bir yaklaşım .

$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
Bu güzel çalışıyor, SSH erişiminiz olmadığında ve FTP'nin çok sayıda dosya ve klasörü yinelemeli olarak silmesi tam anlamıyla saatler sürüyorsa ... bu satırlarla 3 saniyeden daha kısa sürede 35000 dosyayı sildim!
guari

PHP 7.1 kullanıcıları için: $ file yerine $ file-> getRealPath () kullanılmalıdır. Aksi takdirde, PHP size unlink'in SplFileInfo örneği değil, bir yol gerektirdiğini söyleyen bir hata verecektir.
KeineMaster

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

unlink ('/ path / to / directory /'.$ fileInfo-> getFilename ()) olmalıdır; çünkü bağlantıyı kaldırma yoluna girer. Yine de iyi bir cevap.
Vic

8
Hatta unlink ($ fileInfo-> getPathname ()); bu da dosyanın tam yolunu verecektir. php.net/manual/tr/directoryiterator.getpathname.php
Josh Holloway

'DirectoryIterator' alt dizinler üzerinde de yinelenmiyor mu? Bu durumda 'bağlantıyı kaldır' bu gibi durumlarda bir uyarı oluşturur. Döngünün gövdesi Yamiko'nun cevabında daha fazla görünmemeli ve 'bağlantıyı kaldır' çağırmadan önce her girişi bir dosya olup olmadığını kontrol etmemeli mi?
Andreas Linnert

19

Http://php.net/unlink adresindeki bu kod :

/**
 * 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

Bkz. Readdir ve bağlantıyı kaldırma .

<?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

Hepsini okuyan ve daha sonra iki adımda silinen bir çok dosya içeren bir klasörünüz olduğu varsayılıyor. Dosyaları silmenin en iyi yolunun sadece bir sistem komutu kullanmak olduğuna inanıyorum.

Örneğin linux üzerinde:

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

Veya özyinelemeli bir işlev yazmaya gerek kalmadan özyinelemeli silme istiyorsanız

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

PHP tarafından desteklenen tüm işletim sistemleri için aynı komutlar bulunur. Bunun, dosyaları silmenin GERÇEK BİR yolu olduğunu unutmayın. $ absolutePathToFolder bu kodu çalıştırmadan önce kontrol edilmeli ve güvenceye alınmalıdır ve izinler verilmelidir.


2
$absolutePatToFolderHiç boş değilse , bu yöntemi kullanarak biraz güvensiz
Lawrence Cherone

@LawrenceCherone Diğer alternatifler daha güvenli mi?
robsch

3
@LawrenceCherone Umarım kimse kök izinleriyle bugün php çalıştırmaz. Ciddi olarak, yukarıdaki fonksiyonların hepsi gibi, girdinin "güvenli" olmasını bekliyorum.
Dario Corno

En çok oy alan çözümler, www veya www-data'nın sahibi olmadığı geliştirme ortamlarında çalışmaz. Klasörün uygun haklarının ayarlandığından emin olmak sunucu yöneticisine bağlıdır. exec İşleri halletmek için çok değerli bir araçtır ve büyük güç vs ile stackoverflow.com/a/2765171/418974
Christian BONATO

@LawrenceCherone tamamen haklısın Cevabım sadece performans nedenleriyle çok özel bir durum içindi. Cevabımı notlarınıza göre değiştirdim.
Dario Corno


4

Başka bir çözüm: Bu Sınıf, alt dizinlerdeki tüm dosyaları, alt dizinleri ve dosyaları siler.

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

unlinkr işlevi, komut dosyasının kendisini silmediğinden emin olarak verilen yoldaki tüm klasörleri ve dosyaları yinelemeli olarak siler.

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

bu komut dosyasını yerleştirdiğiniz tüm dosya ve klasörleri silmek istiyorsanız aşağıdaki gibi adlandırın

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

Sadece php dosyalarını silmek istiyorsanız aşağıdaki gibi çağırın

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

dosyaları silmek için başka bir yol da kullanabilirsiniz

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

Bu, home / user / temp dizinindeki tüm dosyaları silecektir.


3

Kopyalama, taşıma, silme, boyut hesaplama, vb. İçin genel amaçlı bir dosya ve klasör işleme sınıfı yayınlandı.

https://gist.github.com/4689551

Kullanmak:

Tek bir dosyayı veya bir dizi klasörü / dosyayı kopyalamak (veya taşımak) için:

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

Tek bir dosyayı veya yoldaki tüm dosya ve klasörleri silin:

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

Bir klasör kümesindeki tek bir dosyanın veya bir dosya kümesinin boyutunu hesaplayın:

$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

Benim için çözüm readdiriyi ve bir cazibe gibi çalıştı. İle glob, bazı senaryolarda işlev başarısız oldu.

// 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

Dosyaları alt klasörlerden kaldırmak için @Stichoza'nın cevabını güncelledim.

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

"Pusheh" adında bir paket var. Bunu kullanarak, bir dizini temizleyebilir veya bir dizini tamamen kaldırabilirsiniz ( Github bağlantısı ). Bu bulunanlarda Packagist da.

Örneğin, Tempdizini silmek istiyorsanız şunları yapabilirsiniz:

Pusheh::clearDir("Temp");

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

İlgileniyorsanız, wiki'ye bakın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.