Keep only the last 3 backup files

Asked

Viewed 99 times

0

I have a system that backs up information and saves it in a folder with this title: db-backup-20150308-034000.sql which is a variant title according to date and time, let’s see that I do not want to accumulate files so I want to keep only the 3 last saved files, how to proceed?

the file title is made from the following format:

'db-backup-' . date("Ymd-His", time()) . '.sql'

2 answers

2

What you’re going to have to do is basically the following:

  1. Fetch all files from the directory and save them in one array using readdir.
  2. Treat the name of the searched files and use usort to organize things.
  3. After that, get the first 3 values of the array (will be the most recent files) and save in a array separate.
  4. Rescan the file name and check which files are not the latest 3 and delete them, use glob makes the process easier.

Follow a quick example I did, you can improve some things on it later if you prefer:

<?php
    $datetime   = array();
    $dir        = "test";
    $handle     = opendir($dir);

    if ($handle) {
        while ( $entry = readdir($handle) ) {
            // Não sei porquê aqui listou 2 arquivos inexistentes com nomes "." e "..", não sei mesmo.
            // Então montei essa condição, se você ver o erro no código me avise por favor.
            if ( strlen($entry) > 3 ) {
                // Adiciona à nossa array os valores no formato YmdHis
                array_push( $datetime,  str_replace( "-", "", substr($entry, 10, -4) ) );
            }
        }
        closedir($handle);

        // Aqui utilizamos o usort pra definir uma função de retorno que compara
        // os valores da array.
        usort($datetime, "doCompare");

        // Aqui já sabemos que os 3 arquivos mais recentes são os 3 primeiros da array
        // Criamos uma array auxiliar para remontarmos o nome completo dos arquivos
        $leave = array_slice($datetime, 0, 3);
        $leave_files = array();

        foreach ($leave as $key => $value) {
            array_push($leave_files, $dir . "/db-backup-" . date("Ymd-His", strtotime($value)) . ".txt");
        }

        // Usamos um glob para pegar os nomes dos arquivos do diretório
        $files = glob( $dir . "/*");

        foreach ($files as $file) {
            // Verifica se o arquivo NÃO ESTÁ na array de arquivos a serem mantidos
            // Se não estiver, tenta deletar o arquivo
            if ( !in_array($file, $leave_files) ) {
                if ( unlink($file) ) {
                    echo "- Arquivo deletado: " . $file . "<br />";
                } else {
                    echo "Falha no arquivo: " . $file . "<br />";
                }
            } else {
                echo "+ Arquivo mantido: " . $file . "<br />";
            }
        }
    }

    function doCompare($a, $b) {
        $t1 = strtotime($a);
        $t2 = strtotime($b);

        return ($t2 - $t1);
    }

List of all files in the directory before execution:

db-backup-20131111-224750.txt
db-backup-20140101-001712.txt
db-backup-20140123-153000.txt
db-backup-20140308-034000.txt
db-backup-20150101-001712.txt
db-backup-20150220-132907.txt
db-backup-20140123-153702.txt
db-backup-20140123-153212.txt

Exit from execution:

- Arquivo deletado: test/db-backup-20131111-224750.txt
- Arquivo deletado: test/db-backup-20140101-001712.txt
- Arquivo deletado: test/db-backup-20140123-153000.txt
- Arquivo deletado: test/db-backup-20140123-153212.txt
- Arquivo deletado: test/db-backup-20140123-153702.txt
+ Arquivo mantido: test/db-backup-20140308-034000.txt
+ Arquivo mantido: test/db-backup-20150101-001712.txt
+ Arquivo mantido: test/db-backup-20150220-132907.txt

2

<?php

/*
Quantidade de arquivos para manter no diretório
*/
$files_qty = 3;

/*
Diretório base
*/
$dir_base = dirname(__FILE__) . DIRECTORY_SEPARATOR;

/*
Inicia iteração no diretório
*/
$iterator = new DirectoryIterator($dir_base);
foreach( $iterator as $fileinfo )
{
    if( $fileinfo -> isFile() )
    {
        /*
        Guarda os dados num array.
        As chaves do array são números inteiros criados automaticamente.
        O valor de cada array guarda a data de modificação/criação, em formato timestamp, do arquivo contatenado com o nome do mesmo.
        Exemplo: "1423409607 - arquivo_test.php" (sem aspas)
        */
        $arr[] = $fileinfo -> getMTime() . ' - ' . $fileinfo -> getFilename();
    }
}

/*
Verifica se o carray contém mais de 3 ítens.
*/
if( $arr > $files_qty )
{
    /*
    Reverte a ordenação do array baseado na string.
    É por isso que o timestamp é salvo concatenado ao nome do arquivo. Para facilitar nesse momento de ordenação e aplicação do array_slice()
    */
    rsort($arr);

    /*
    Aplicando a função array_slice(), a qual removerá os 3 primeiros da lista.
    A idéia é manter no array somente os nomes dos arquivos que devem ser excluídos.
    A função array_slice() é similar a função substr(), só que é usada para arrays.
    */
    $arr = array_slice( $arr, $files_qty );

    /*
    Itera pelo array resultante, excluindo todos os arquivos contidos na lista.
    */
    foreach( $arr as $v )
    {
        /*
        Apenas para debugar
        */
        echo PHP_EOL . $dir_base . substr( $v, 13 );

        /*
        Descomente a linha abaixo para proceder.
        Cuidado onde for executar pois os arquvios são excluídos permamentemente.
        A função substr() é necessária para pular a string que contém o timestamp e os caracteres separadores ( - ). O real nome do arquivo inicia a partir do 14º caracter.
        */
        //unlink( $dir_base . substr( $v, 13 ) );
    }
}
?>
  • the above code will not also delete the file itself that runs it? If it happens to be in the same directory as the files to be removed.

  • Then you have to be very stupid to put the script in the same folder where the files will be deleted right... @Wesley

  • kkkk, you’ll know... at least it worked here :) thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.