2010-02-05 27 views
20

Ho una cartella cache che memorizza i file html. Essi vengono sovrascritti quando necessario, ma un sacco di tempo, le pagine utilizzate raramente vengono memorizzate nella cache in là anche, che appena finiscono per utilizzando lo spazio (dopo 5 settimane, il disco era pieno, con oltre 2,7 milioni di file di cache).Come eliminare i file dalla directory in base alla data di creazione in php?

cosa è il modo migliore per ciclo attraverso una directory che contiene diverse centinaia di migliaia di file, e rimuovere i file che sono più vecchi di 1 giorno?

+4

C'è un motivo per cui è necessario farlo in PHP? Potresti trovare un linguaggio di scripting della shell più appropriato per questo. –

+0

Puoi fare tutto questo e altro usando [il comando 'find' di Linux] (https://askubuntu.com/a/589224/372950) – rinogo

risposta

37

Penso che potresti andare in giro questo ciclo attraverso la directory con readdir ed eliminare in base alla data e ora:

<?php 
$path = '/path/to/files/'; 
if ($handle = opendir($path)) { 

    while (false !== ($file = readdir($handle))) { 
     $filelastmodified = filemtime($path . $file); 
     //24 hours in a day * 3600 seconds per hour 
     if((time() - $filelastmodified) > 24*3600) 
     { 
      unlink($path . $file); 
     } 

    } 

    closedir($handle); 
} 
?> 

Il if((time() - $filelastmodified) > 24*3600) selezionerà file più vecchi di 24 ore (24 ore tempi di 3600 secondi all'ora). Se si desidera giorni, dovrebbe leggere ad esempio 7 * 24 * 3600 per i file più vecchi di una settimana.

Si noti inoltre che filemtime restituisce l'ora dell'ultima modifica del file, invece che la data di creazione.

4

La funzione di seguito elenca il file in base alla loro data di creazione:

private function listdir_by_date($dir){ 
    $h = opendir($dir); 
    $_list = array(); 
    while($file = readdir($h)){ 
    if($file != '.' and $file != '..'){ 
     $ctime = filectime($dir . $file); 
     $_list[ $file ] = $ctime; 
    } 
    } 
    closedir($h); 
    krsort($_list); 
    return $_list; 
} 

Esempio:

$_list = listdir_by_date($dir); 

Ora è possibile scorrere l'elenco per vedere le loro date ed eliminare di conseguenza:

$now = time(); 
$days = 1; 
foreach($_list as $file => $exp){ 
    if($exp < $now-60*60*24*$days){ 
    unlink($dir . $file); 
    } 
} 
3

Prova SplIterators

// setup timezone and get timestamp for yesterday 
date_default_timezone_set('Europe/Berlin'); // change to yours 
$yesterday = strtotime('-1 day', time()); 

// setup path to cache dir and initialize iterator 
$path  = realpath('/path/to/files'); // change to yours 
$objects = new RecursiveIteratorIterator(
       new RecursiveDirectoryIterator($path)); 

// iterate over files in directory and delete them 
foreach($objects as $name => $object){ 
    if ($object->isFile() && ($object->getCTime() < $yesterday)) { 
     // unlink($object); 
     echo PHP_EOL, 'deleted ' . $object; 
    } 
} 

Creation Time is only available on Windows.

9

Dovrebbe essere

if((time()-$filelastmodified) > 24*3600 && is_file($file)) 

per evitare errori per i . e .. directory.

+1

Meglio controllare se' $ file == '.' || $ file == '..' 'per risparmiare tempo controllando' is_file() 'ogni volta ... – barell

-1

Cambiando soluzione @ di Pawel ho creato funzione qui sotto. All'inizio ho dimenticato di aggiungere "percorso" al nome del file, che impiega mezz'ora per scoprirlo.

public function deleteOldFiles ($hours=24) { 
    $path='cache'.DS; 
    if ($handle = opendir($path)) { 
     while (false !== ($file = readdir($handle))) { 
      $filelastmodified = filemtime($path.$file); 
      if((time()-$filelastmodified) > 24*3600 && is_file($path.$file)) 
      { 
       unlink($path.$file); 
      } 
     } 
     closedir($handle); 
    } 
} 
0

solo per notare confronto temporale di Gordon (vedi sopra: https://stackoverflow.com/a/2205833/1875965) è l'unica corretta quando si confrontano a 'giorni', piuttosto che '24 ore, in quanto non tutti i giorni hanno 24 ore (estate/inverno, ecc) .

E.g. utilizzare

// setup timezone and get timestamp for yesterday 
date_default_timezone_set('Europe/Berlin'); // change as appropriate 
$yesterday = strtotime('-1 day', time()); 

quando si confronta la data del file.

Questo potrebbe non essere un grosso problema, ma può portare a comportamenti imprevisti quando si lavora con settimane/mesi, ecc. Ho trovato il modo migliore di attenersi a utilizzare il metodo di cui sopra in quanto renderà qualsiasi processo che coinvolge le date/tempi coerenti ed evitare confusione.

controllare anche ciò che il fuso orario è per le date di file, come a volte il valore di default per PHP è diverso dal fuso orario del sistema.

Cordiali saluti, Sandra.

+0

buon punto. per lunghi periodi, dovrebbe prendere in considerazione il fuso orario. . . – Atara

1
/* Detele Cache Files Here */ 
$dir = "cache/"; /** define the directory **/ 

/*** cycle through all files in the directory ***/ 
foreach (glob($dir."*") as $file) { 
//foreach (glob($dir.'*.*') as $file){ 

/*** if file is 24 hours (86400 seconds) old then delete it ***/ 
if (filemtime($file) < time() - 3600) { // 1 hour 
    unlink($file); 
    } 
} 

Sto usando questo, spero che sia d'aiuto.

Problemi correlati