Автоматическое удаление всех файлов после x-времени

Как вы автоматически удаляете все файлы в подкаталоге после x-времени (скажем, через 24 часа) - без использования команды cronjob с сервера или pl. Как вы можете сделать это, просто используя PHP-код или просто зайдя на страницу, не нажимая что-то, и команда запускается автоматически.


person jones    schedule 17.12.2009    source источник


Ответы (6)


Ответ на последний комментарий из моего первого ответа. Я собираюсь написать пример кода, поэтому я создал еще один ответ вместо добавления еще одного комментария.

Чтобы удалить файлы с пользовательским расширением, вы должны реализовать код:

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

    while (false !== ($file = readdir($handle))) {
        if ((time()-filectime($path.'/'.$file)) < 86400) {  // 86400 = 60*60*24
          if (preg_match('/\.txt$/i', $file)) {
            unlink($path.'/'.$file);
          }
        }
    }
  }
?>

Комментарий: 1. В этом примере используется регулярное выражение /\.txt$/i, что означает, что будут удалены только файлы с расширением txt. Знак «$» означает, что имя файла должно заканчиваться строкой «.txt». Флаг 'i' указывает, что сравнение будет нечувствительным к регистру. Подробнее о функции preg_match().

Кроме того, вы можете использовать функцию strripos() для поиска файлов с определенным расширением. Вот фрагмент кода:

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

    while (false !== ($file = readdir($handle))) {
        if ((time()-filectime($path.'/'.$file)) < 86400) {  // 86400 = 60*60*24
          if (strripos($file, '.txt') !== false) {
            unlink($path.'/'.$file);
          }
        }
    }
  }
?>

Комментарий. Этот пример кажется более очевидным. Результат strripos() также может быть достигнут комбинацией двух функций: strrpos(strtolower($file), '.txt'), но, ИМХО, лучше использовать меньше функций в коде, чтобы сделать его читабельнее и меньше. Пожалуйста, внимательно прочитайте предупреждение на странице функции strripos() (блок возвращаемых значений).

Еще одно важное замечание: если вы используете систему UNIX, удаление файла может завершиться ошибкой из-за прав доступа к файлу. Вы можете проверить руководство по функции chmod().

Удачи.

person Alex    schedule 21.12.2009
comment
Ты прав. Я не писал о функции glob() просто потому, что никогда раньше ею не пользовался. :) Спасибо за ваш комментарий. - person Alex; 21.12.2009
comment
Отметил Алекс и большое спасибо - person jones; 23.12.2009

Вы можете использовать основные функции PHP filectime() и unlink(), чтобы проверить время создания файла и удалить его файл/файлы.

РЕДАКТИРОВАТЬ. Пример кода:

  if ($handle = opendir('/path/to/files')) {

    while (false !== ($file = readdir($handle))) {
        if (filectime($file)< (time()-86400)) {  // 86400 = 60*60*24
          unlink($file);
        }
    }
  }
person Alex    schedule 17.12.2009
comment
Это только скелет функции. Вы можете добавить любые условия, например. файлы с пользовательскими расширениями или файлы, соответствующие определенному шаблону и т. д. - person Alex; 17.12.2009
comment
Пожалуйста. Я рад помочь вам. Если этот ответ подходит вам, вы можете принять его, поставив галочку рядом с моим ответом. - person Alex; 19.12.2009
comment
я пытался добавить для пользовательских условий файла расширения, но не работает, у вас есть несколько примеров? - person jones; 21.12.2009

Итак, приступим к PHP-скрипту, который удаляет файлы, которым X дней.

<?
$days = 1;
$dir = dirname ( __FILE__ );

$nofiles = 0;

    if ($handle = opendir($dir)) {
    while (( $file = readdir($handle)) !== false ) {
        if ( $file == '.' || $file == '..' || is_dir($dir.'/'.$file) ) {
            continue;
        }

        if ((time() - filemtime($dir.'/'.$file)) > ($days *86400)) {
            $nofiles++;
            unlink($dir.'/'.$file);
        }
    }
    closedir($handle);
    echo "Total files deleted: $nofiles \n";
}
?>

Теперь вставьте этот код и сохраните его как файл php, загрузите его в папку, откуда вы хотите удалить файлы. Вы можете увидеть в начале этого php-кода

$days = 1;

который устанавливает количество дней, например, если вы установите его на 2, то файлы старше 2 дней будут удалены. В основном это то, что происходит, когда вы запускаете скрипт, получаете текущий каталог и читаете записи файла, пропускаете «.» для текущего каталога и далее проверяете, есть ли какие-либо другие каталоги,

if ( $file == '.' || $file == '..' || is_dir($dir.'/'.$file) ) {
           continue;
}

если запись файла не является каталогом, то она извлекает время изменения файла (время последнего изменения) и сравнивает, если это количество дней назад

if ((time() - filemtime($dir.'/'.$file)) > ($days *86400)) {
            $nofiles++;
            unlink($dir.'/'.$file);
}

если условие становится истинным, то он удаляет файл с помощью php-функции unlink(). Наконец закрывает каталог и выходит. Я также добавил счетчик для подсчета количества удаляемых файлов, который будет отображаться в конце процесса удаления. Поэтому поместите файл php в каталог, который требует удаления файла, и запустите его.

Надеюсь, это поможет :)

person Raymond    schedule 15.08.2016

Вот еще один пример, который использует GLOB и удалит любой файл

$files = glob('path/to/your/files/*');

foreach($files as $file) { // iterate files
    // if file creation time is more than 5 minutes
    if ((time() - filectime($file)) > 3600) {  // 86400 = 60*60*24
        unlink($file);
    }
}

или если вы хотите исключить определенные файлы

$files = preg_grep('#\.txt#', glob('/path/to/your/files/*'), PREG_GREP_INVERT);
person AdRock    schedule 16.12.2015

После попытки использовать эти примеры я столкнулся с парой проблем:

  1. Оператор сравнения должен быть больше, но не меньше
  2. filemtime возвращает измененное время. filectime — время изменения данных индексного дескриптора файла; то есть, когда разрешения, владелец, группа или другие метаданные из inode обновляются, что может привести к неожиданным результатам.

Я изменил пример, чтобы использовать filemtime, и исправил сравнение следующим образом:

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

    while (false !== ($file = readdir($handle))) {
        if ((time()-filemtime($path.'/'.$file)) > 86400) {  // 86400 = 60*60*24
          if (preg_match('/\.txt$/i', $file)) {
            unlink($path.'/'.$file);
          }
        }
    }
  }
?>
person ssmithereens    schedule 02.01.2017

Я использую команду оболочки AT, хотя это похоже на cronjob

php:

exec("echo rm /somedir/somefile.ext|at now +24 hours");
person pwr    schedule 13.10.2012