2010-02-05 5 views
20

J'ai un dossier de cache qui stocke les fichiers html. Ils sont remplacés en cas de besoin, mais la plupart du temps, les pages rarement utilisées sont également mises en cache, qui finissent par utiliser l'espace (après 5 semaines, le disque était plein avec plus de 2,7 millions de fichiers cache).Comment supprimer des fichiers du répertoire en fonction de la date de création en PHP?

Quel est le meilleur moyen de faire une boucle dans un répertoire contenant plusieurs centaines de milliers de fichiers et de supprimer des fichiers de plus de 1 jour?

+4

Y at-il une raison pour laquelle vous avez besoin de faire cela en PHP? Vous pourriez trouver un langage shell-scripting plus approprié pour cela. –

+0

Vous pouvez faire tout cela et plus en utilisant [la commande Linux 'find'] (https://askubuntu.com/a/589224/372950) – rinogo

Répondre

37

Je pense que vous pourriez aller à propos de ceci en boucle à travers le répertoire avec readdir et supprimer en fonction de l'horodatage:

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

Le if((time() - $filelastmodified) > 24*3600) sélectionnera les fichiers de plus de 24 heures (24 heures fois 3600 secondes par heure). Si vous voulez des jours, il faut lire par exemple 7 * 24 * 3600 pour les fichiers de plus d'une semaine.

Notez également que filemtime renvoie l'heure de la dernière modification du fichier, au lieu de la date de création.

4

La fonction ci-dessous répertorie le fichier en fonction de leur date de création:

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

Exemple:

$_list = listdir_by_date($dir); 

boucle Maintenant, vous pouvez parcourir la liste pour voir leurs dates et supprimer en conséquence:

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

Essayez 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

Il devrait être

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

pour éviter les erreurs pour les . et .. répertoires.

+1

Il vaut mieux vérifier si fichier' $ == « » || $ file == '..' 'pour gagner du temps en vérifiant' is_file() 'à chaque fois ... – barell

-1

En changeant la solution de @ pawel j'ai créé la fonction ci-dessous. Au début, j'ai oublié d'ajouter "chemin" au nom de fichier, qui prend ma demi-heure pour le savoir. juste

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

à noter la comparaison du temps de Gordon (voir ci-dessus: https://stackoverflow.com/a/2205833/1875965) est la seule correcte lorsque l'on compare à «jours plutôt que '24 les heures, comme tous les jours ont 24 heures (heure d'été/hiver, etc.) .

E.g. utiliser

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

lors de la comparaison de la date du fichier. Cela peut ne pas être un gros problème, mais peut conduire à un comportement inattendu lorsque vous travaillez avec des semaines/mois, etc. J'ai trouvé préférable de m'en tenir à la méthode ci-dessus car il va faire tout processus impliquant des dates/fois cohérentes et éviter la confusion.

Vérifiez également le fuseau horaire pour les dates de fichier, car la valeur par défaut pour PHP diffère parfois du fuseau horaire du système.

Cordialement, Sandra.

+0

bon point. pendant de longues périodes, devrait considérer le fuseau horaire. . . – 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); 
    } 
} 

J'utilise ceci, j'espère que ça aide.

Questions connexes