2010-02-05 14 views
20

Tengo una carpeta de caché que almacena archivos html. Se sobrescriben cuando es necesario, pero la mayoría de las veces, las páginas que se usan con poca frecuencia también se almacenan en caché, que acaban utilizando espacio (después de 5 semanas, la unidad estaba llena con más de 2,7 millones de archivos de caché).Cómo eliminar archivos del directorio en función de la fecha de creación en php?

¿Cuál es la mejor forma de recorrer un directorio que contiene varios cientos de miles de archivos y eliminar archivos que tienen más de 1 día?

+4

¿Hay alguna razón por la que necesites hacer esto en PHP? Es posible que encuentre un lenguaje de guiones de shell más apropiado para esto. –

+0

Puede hacer todo esto y más usando [el comando 'find' de Linux] (https://askubuntu.com/a/589224/372950) – rinogo

Respuesta

37

Creo que podría ir sobre esto mediante un bucle a través del directorio con readdir y borrar basado en la marca de tiempo:

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

El if((time() - $filelastmodified) > 24*3600) seleccionará archivos de más de 24 horas (24 horas 3.600 segundos veces por hora). Si quería días, debería leer, por ejemplo, 7 * 24 * 3600 para archivos de más de una semana.

Además, tenga en cuenta que filemtime devuelve la hora de la última modificación del archivo, en lugar de la fecha de creación.

4

La función siguiente se enumeran los archivos en función de su fecha de creación:

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

Ejemplo:

$_list = listdir_by_date($dir); 

Ahora puede recorrer la lista para ver sus fechas y eliminar en consecuencia:

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

Trate 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

Debe ser

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

para evitar errores de los . y .. directorios.

+1

Es mejor verificar si' $ file == '.' || $ file == '..' 'para ahorrar tiempo al verificar' is_file() 'cada vez ... – barell

-1

Al cambiar la solución de @ pawel creé la función a continuación. Al principio me olvidé de agregar "ruta" al nombre del archivo, lo que me lleva media hora averiguarlo.

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

para notar comparación del tiempo de Gordon (véase más arriba: https://stackoverflow.com/a/2205833/1875965) es la única correcta cuando se comparan a 'días' en lugar de '24 horas, ya que no todos los días tienen 24 horas (horario de verano/invierno, etc.) .

E.g. use

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

al comparar la fecha del archivo.

Esto puede no ser un gran problema, pero puede conducir a un comportamiento inesperado cuando se trabaja con semanas/meses, etc. Me pareció mejor seguir utilizando el método anterior, ya que hará que cualquier proceso involucre fechas/tiempos consistentes y evitar confusiones.

También compruebe qué es la zona horaria para las fechas del archivo, ya que a veces el valor predeterminado para PHP difiere de la zona horaria del sistema.

Saludos cordiales, Sandra.

+0

buen punto. durante largos períodos, debe considerar la zona horaria. . . – 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); 
    } 
} 

Estoy usando esto, espero que ayude.

Cuestiones relacionadas