Delete automated files

Asked

Viewed 228 times

4

Good guys, I have a system, where practically daily uploads are sent via pdf files. After a while it has a lot of accumulated file.

For example: Upo 100 PDF hj files, tomorrow I put 20. So, from the day I skipped the 100 PDF files, after 3 months it erases those 100.. the next day the same scheme and erases the 20 and so on, but it is not erased all at once.

Any idea or help?

Thanks in advance!

I have this PHP programming below,

    <?php
  $dateFormat = "d-m-Y H:i:s";
  $dir = 'uploads/*/*';

  if(isset($_POST['excluir'])){
    if($objs == glob($dir)) {
    foreach($objs as $obj) {
      if (is_dir($obj)) continue; // Verifica se o arquivo é um diretório, se for, tudo que está abaixo é desconsiderado

      $dateFile = strtotime(date($dateFormat, filemtime($obj))); // Data da última modificação do arquivo convertida em time;
      $dateToRemove = strtotime(date($dateFormat, filemtime($obj) + (60 * 5))); // Tempo da última modificação + 3 meses convertida em time;
      if($dateFile >= $dateToRemove) unlink($obj); // Exclui o arquivo se este possuir 03 meses desde a última modificação
    }
}
}
?> 

Button:

<button class="btn btn-danger" name="excluir" onclick="return confirm('Tem certeza que deseja apagar todos os Boletos?                         ATENÇÃO! ESSA AÇÃO NÃO TERÁ VOLTA!')" >APAGAR TODOS OS BOLETOS</button>

EDIT: Code edited as explained. I did tests with 1 minute, upei files, waited 1 minute.. upei a few more, I went to delete and deleted all.

  • Use the function filemtime to capture the date of the last file modification. This function will return the time in the default Unix timestamp; done this, just compare the time interval with the function date or DateTime::diff

  • Would you have any example?

3 answers

3

You can make a PHP script that reads the creation date of a file to remove it using the function filectime:

$dateFormat = "Y-m-d"; // Altere para "Y-m-d H:i:s" se quiser levar em consideração os segundos.
$dateToRemove = date($dateFormat, strtotime("-3 months"));
$dir = 'uploads/*/*';

if($objs = glob($dir)) {
    foreach($objs as $obj) {
      if (is_dir($obj)) continue;
      if (date($dateFormat, filectime($obj)) > $dateToRemove) continue;
      unlink($obj);
    }
}

You can save this code in a . php file and run it from time to time. In order not to have to run manually, you can use a tool that runs scheduled scripts at intervals of time defined by you, in Linux scripts of this type are known as CRON and in Windows this feature is known as Scheduled Tasks, available through the Task Scheduler.

You can set it up manually or use an online service like the https://cron-job.org, that will call your PHP page as often as you set.

For more details about the function filectime you can consult the PHP documentation: https://www.php.net/manual/en/function.filectime.php


PS: You may have wondered how I write code if (condicaoFalsa) continue, but is a technique used to increase code maintainability.

You can see an example of this here (in English): https://softwareengineering.stackexchange.com/questions/47789/how-would-you-refactor-nested-if-statements

  • Got it, very good! How do I test if it is working "not to have to wait 3 months", but from my Submit, do one test per minute, for example?

  • 1

    You can do a test by creating a test file by changing the parameter "-3 months" for "-1 minute" and run the script a minute after you created the file.

  • Strangely, I do it to test with a minute. Upo the file, wait a minute, upo again one and when I give the Submit, it erases the 2. :(

  • 1

    You can give a echo(date($dateFormat, filectime($obj)) to verify how this value is being computed. The most likely cause is that as the date format is only day, month and year, it takes into consideration only the day, causing all the files to be deleted. You can test by replacing the $dateFormatat value Y-m-d H:i:s, which shall also take into account the second.

2


Hello! I noticed there’s a error syntax in your code:

if($objs = glob($dir)){

Right:

if($objs == glob($dir)){

In my view, the explanation of your problem was not very clear. I could give more details of your problem?

@EDIT - 28/05

From the answer of Keven Carneiro I adapted the script in a way that I believe will solve your problem.

$dateFormat = "d-m-Y";
$dir = 'uploads/*/*';

if($objs == glob($dir)) {
    foreach($objs as $obj) {
      if (is_dir($obj)) continue; // Verifica se o arquivo é um diretório, se for, tudo que está abaixo é desconsiderado

      $dateFile = strtotime(date($dateFormat, filemtime($obj))); // Data da última modificação do arquivo convertida em time;
      $dateToRemove = strtotime(date($dateFormat, filemtime($obj) + (3600 * 24 * 90))); // Tempo da última modificação + 3 meses convertida em time;
      if(time() >= $dateToRemove) unlink($obj); // Exclui o arquivo se este possuir 03 meses desde a última modificação
    }
}

If you want to test the difference in hours you should:

  1. Change "$dateFormat" to "d-m-Y H:i:s";
  2. Change the next line by changing the sum time to, for example, 3600 only. (One-hour value)

$dateToRemove = strtotime(date($dateFormat, filemtime($obj) + (3600 * 24 * 90)));

Make sure to check if the amount being received in $objs is valid to enter the first condition:

if($objs == glob($dir)) {

I tried to explain as much as possible what each function does, but you can ask questions here or consult the documentation! I hope I’ve helped.

  • I will try to be clearer, Every day several pdfs are upados. Today I upo 100 pdfs, tomorrow I upo 20 pdf. After 3 months, the deletion is automatic for these 100 pdfs, the next day is the same for the 20 pdfs and so on. Any way or solution? thank you for the correction!

  • Comparison, file does not erase :(

  • Check if from the editing of my reply you can achieve success.

  • Thank you, really! To change for 5 minutes: (3600 * 24 * 90)); and to do tests. 3600 would be seconds? 24 would be 1 day? and 90 days/3 months, correct? in 5 minutes it would be like?

  • 3600 is the value for an hour in seconds. If you want to test 05 minutes, just convert the value of 05 minutes into seconds, 60 * 5, which would give 300 seconds.

  • Can I be very persistent, sorry. Could you check the code for me and see if it’s right? I did a test and it didn’t work yet. I edited up there

  • Hello, I have edited an excerpt of the code and it is working. Copy the code entirely and replace what you are using. Note that if you are copying a file to the folder, the date of its last modification will not be the date of the copy. To avoid this, remember to create new files.

  • Works only on localhost or hosting(linux) tbm works?

  • It works in any environment. Remember that you can debug step by step and see the values that are being received in order to solve the problem. For example, you could delete the unlink() function and check if the condition is falling at that point, and for what reason.

  • I have some folders after uploads, example: uploads/a1 , uploads/a2 and the files are inside them. I will try to test everything tonight. The * meets and understands how it only has files in these a1, a2 folders?

  • glob("uploads//") will return an array of all files from all folders within uploads.

Show 6 more comments

1

Here to work I changed the date format to : $dateFormat = "Y-m-d";

Browser other questions tagged

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