【问题标题】:How to delete files from directory based on creation date in php?如何根据php中的创建日期从目录中删除文件?
【发布时间】:2011-01-13 10:14:32
【问题描述】:

我有一个存储 html 文件的缓存文件夹。它们在需要时被覆盖,但很多时候,很少使用的页面也被缓存在那里,最终会占用空间(5 周后,驱动器已满,有超过 270 万个缓存文件)。

遍历包含数十万个文件的目录并删除超过 1 天的文件的最佳方法是什么?

【问题讨论】:

  • 您是否有理由需要在 PHP 中执行此操作?您可能会发现一种更适合于此的 shell 脚本语言。
  • 您可以使用the Linux find command完成所有这些以及更多操作

标签: php


【解决方案1】:

以下函数根据创建日期列出文件:

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

示例:

$_list = listdir_by_date($dir);

现在您可以遍历列表以查看其日期并相应地删除:

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

【讨论】:

  • 为什么有人要先循环获取排序列表,然后再循环删除?对开销没有意义。
【解决方案2】:

我认为您可以通过使用 readdir 循环目录并根据时间戳删除来解决此问题:

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

if((time() - $filelastmodified) &gt; 24*3600) 将选择超过 24 小时(24 小时乘以 3600 秒/小时)的文件。如果您想要几天,对于超过一周的文件,它应该读取例如 7*24*3600。

另外,请注意filemtime 返回文件的最后修改时间,而不是创建日期。

【讨论】:

    【解决方案3】:

    试试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.

    【讨论】:

      【解决方案4】:

      应该是

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

      避免... 目录出错。

      【讨论】:

      • 最好检查 $file == '.' || $file == '..' 是否可以节省每次检查 is_file() 的时间...
      【解决方案5】:

      通过更改@pawel 的解决方案,我在下面创建了函数。 起初我忘记在文件名中添加“路径”,这需要我半个小时才能找到。

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

      【讨论】:

        【解决方案6】:

        请注意 Gordon 的时间比较(见上文:https://stackoverflow.com/a/2205833/1875965)是与“天”而不是“24 小时”比较时唯一正确的比较,因为并非所有天都有 24 小时(夏季/冬季等)。

        例如使用

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

        比较文件日期时。

        这可能不是一个大问题,但是当您处理几周/几个月等时可能会导致意外行为。我发现最好坚持使用上述方法,因为它会使任何涉及日期/时间的过程一致并避免混淆。

        还要检查文件日期的时区,因为有时 PHP 的默认时区与系统时区不同。

        亲切的问候,桑德拉。

        【讨论】:

          【解决方案7】:
          /* 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);
              }
          }
          

          我正在使用这个,希望对你有帮助。

          【讨论】:

            【解决方案8】:
            $directory = $_SERVER['DOCUMENT_ROOT'].'/pathfromRoot/';
            
            $files = array_slice(scandir($directory), 2);
            foreach($files as $file)
            {
                // $extension      = substr($file, -3, 3); 
                // if ($extension == 'jpg') // in case you only want specific files deleted
                // {
                $stat = stat($directory.$file);
                $filedate = date_create(date("Y-m-d", $stat['ctime']));
                $today = date_create(date("Y-m-d"));
                $days = date_diff($filedate, $today, true);
                // dd($days);
                if ($days->days > 180) 
                { 
                    unlink($directory.$file);
                }
                 // } 
            }
            

            【讨论】:

              猜你喜欢
              • 2018-07-16
              • 2021-08-21
              • 1970-01-01
              • 2017-07-09
              • 2013-07-30
              • 1970-01-01
              • 2013-01-15
              • 1970-01-01
              • 2015-01-31
              相关资源
              最近更新 更多