Удалите все файлы, но сохраните самые новые.

У меня есть несколько (заархивированных) файлов резервных копий в каталоге; имена файлов, начинающиеся с «backup-».

Я хочу удалить все файлы, которые старше, скажем, 7 дней, но всегда должен оставаться один файл (самый новый), иначе у меня больше нет файла резервной копии.

У меня есть исходный код (см. ниже), который удалит ВСЕ файлы старше 7 дней, но как всегда сохранять самый новый файл в каталоге? Таким образом, оставшийся может быть старше 7 дней (если он самый новый).

$bu_days=7;
$files="backup*.tar.gz";

foreach(glob($filter) as $fd) {
  if(is_file($fd) && time() - filemtime($fd) >= $bu_days*24*60*60) {unlink($fd);}
}

person ni_hao    schedule 23.11.2016    source источник
comment
Просто посчитайте свои файлы и сломайте; foreach, когда остался только 1 файл?   -  person Thomas C    schedule 23.11.2016
comment
Вам нужно будет сделать некоторые тесты, прежде чем удалять что-либо.   -  person RST    schedule 23.11.2016


Ответы (3)


Вы можете отсортировать файлы по дате, а затем удалить все, кроме первого:

$bu_days=7;
$files="backup*.tar.gz";

//retrieve all files
$theFiles = glob($files);

//combine the date as a key for each file
$theFiles = array_combine(array_map("filemtime", $theFiles), $theFiles);

//sort them, descending order
krsort($theFiles);

//remove the first item
unset($theFiles[0]);

foreach($theFiles as $fd){
    if(is_file($fd) && time() - filemtime($fd) >= $bu_days*24*60*60) {unlink($fd);}
}
person Veve    schedule 23.11.2016
comment
Спасибо, Веве, я думаю, что в вашем источнике есть небольшая ошибка: вы забыли $ (перед theFiles) в foreach (theFiles as $fd){. - person ni_hao; 23.11.2016
comment
вместо first=true и т. д. вы можете использовать unset(array[0]), что удалит его из массива - person ni_hao; 23.11.2016
comment
@ni_hao Вы правы, я отредактировал свой ответ с помощью вашего совета и лучшего решения, которое не требует многократного доступа к дате файла для каждого файла. - person Veve; 23.11.2016
comment
Спасибо еще раз. Тем временем я хочу быть более гибким, не только сохраняя первый файл, но и определяя, сколько файлов всегда следует хранить. Я также изменил (косметически) вашу строку 'array_combine', и я предпочитаю больше работать с массивами, что привело меня к обновленному источнику. - person ni_hao; 24.11.2016
comment
Оценил вашу помощь. Обновленный источник, опубликованный выше (2 ответа) - person ni_hao; 24.11.2016

Обновленный источник:

//declare after how many days files are too old
$bu_days=7;

//declare how many files always should be kept                              
bu_min=3;

//define file pattern
$files="backup*.tar.gz";

//retrieve all files
$theFiles = glob($files);

//combine the date as a key for each file
$theFiles = array_combine($theFiles, array_map("filemtime", $theFiles));

//sort array, descending order (newest first)
arsort($theFiles);

//return subset of the array keys
$f = array_keys($theFiles);

// keep the first $bu_min files of the array, by deleting them from the array
$f = array_slice($theFiles, $bu_min);

// delete every file in the array which is >= $bu_days days
foreach($theFiles as $fd){
  if(is_file($fd) && time() - filemtime($fd) >= $bu_days*24*60*60) {unlink($fd);}
}
person ni_hao    schedule 24.11.2016

$f = array_keys($theFiles);
$f = array_slice($theFiles, $bu_min);

$f должно быть $theFiles

person mahakala    schedule 23.02.2019