The correct way to delete all files older than 2 days in PHP

PhpFileCaching

Php Problem Overview


Just curious

		$files = glob(cacheme_directory()."*");
		foreach($files as $file)
		{
			$filemtime=filemtime ($file);
			if (time()-$filemtime>= 172800)
			{
				unlink($file);
			}
		}

I just want to make sure if the code is correct or not. Thanks.

Php Solutions


Solution 1 - Php

You should add an is_file() check, because PHP normally lists . and .., as well as sub-directories that could reside in the the directory you're checking.

Also, as this answer suggests, you should replace the pre-calculated seconds with a more expressive notation.

<?php
  $files = glob(cacheme_directory()."*");
  $now   = time();
  
  foreach ($files as $file) {
    if (is_file($file)) {
      if ($now - filemtime($file) >= 60 * 60 * 24 * 2) { // 2 days
        unlink($file);
      }
    }
  }
?>

Alternatively you could also use the DirectoryIterator, as shown in this answer. In this simple case it doesn't really offer any advantages, but it would be OOP way.

Solution 2 - Php

The easiest way is by using DirectoryIterator:

<?php
if (file_exists($folderName)) {
    foreach (new DirectoryIterator($folderName) as $fileInfo) {
        if ($fileInfo->isDot()) {
        continue;
        }
        if ($fileInfo->isFile() && time() - $fileInfo->getCTime() >= 2*24*60*60) {
            unlink($fileInfo->getRealPath());
        }
    }
}
?>

Solution 3 - Php

Another simplier and more modern way, using FilesystemIterator.

I'm using 'logs' directory as an example.

$fileSystemIterator = new FilesystemIterator('logs');
$now = time();
foreach ($fileSystemIterator as $file) {
    if ($now - $file->getCTime() >= 60 * 60 * 24 * 2) // 2 days 
        unlink('logs/'.$file->getFilename());
}

Main advantage is: DirectoryIterator returns virtual directories "." and ".." in a loop. But FilesystemIterator ignores them.

Solution 4 - Php

I reckon this is much tidier and easier to read and modify.

$expire = strtotime('-7 DAYS');

$files = glob($path . '/*');

foreach ($files as $file) {

	// Skip anything that is not a file
	if (!is_file($file)) {
		continue;
	}

	// Skip any files that have not expired
	if (filemtime($file) > $expire) {
		continue;
	}

	unlink($file);
}

Solution 5 - Php

/* Delete 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() - 172800) { // 2 days
    unlink($file);
    }
}

Hope it help you.

Solution 6 - Php

Looks correct to me. I'd just suggest you replace 172800 with 2*24*60*60 for clarity.

Solution 7 - Php

Here is an example of how to do it recursively.

function remove_files_from_dir_older_than_x_seconds($dir,$seconds = 3600) {
	$files = glob(rtrim($dir, '/')."/*");
	$now   = time();
	foreach ($files as $file) {
		if (is_file($file)) {
			if ($now - filemtime($file) >= $seconds) {
				echo "removed $file<br>".PHP_EOL;
				unlink($file);
			}
		} else {
			remove_files_from_dir_older_than_x_seconds($file,$seconds);
		}
	}
}

remove_files_from_dir_older_than_x_seconds(dirname(__file__).'/cache/', (60 * 60 * 24 * 1) ); // 1 day
	

Solution 8 - Php

Be aware that you'll run into problems if you have a very large number of files in the directory.

If you think this is likely to affect you, consider using a lower level approach such as opendir.

Solution 9 - Php

@maksim-t answer can be improved a bit:

  1. Calculate the oldest "allowed" from the start, instead of calculating it on every iteration.
  2. Use Modification time, instead of creation time, because otherwise you may remove files, that were updated recently.
  3. Use getPathname instead of getFilename, so that there will be not need for concatenation of the path.
#Initiate iterator
$fileSI = new FilesystemIterator($this->files);
#Get the oldest allowed time
$oldest = time() - ($maxFileAge * 86400);
#Iterate the files
foreach ($fileSI as $file) {
    #Check time
    if ($file->getMTime() <= $oldest) {
        #Remove the file
        @unlink($file->getPathname());
    }
} 

Solution 10 - Php

/** It deletes old files.
 *  @param string $dir Directory
 *  @param int $secs Files older than $secs seconds
 *  @param string $pattern Files matching $pattern
 */
function delete_oldfiles($dir,$secs,$pattern = "/*")
{
    $now = time();
    foreach(glob("$dir$pattern") as $f) {
      if (is_file($f) && ($now - filemtime($f) > $secs)) unlink($f);
    }
}

Solution 11 - Php

(time()-filectime($path.$file)) < 172800 //2 days

If the current time and file are changed time are within 172800 seconds of each other, then.

 if (preg_match('/\.pdf$/i', $file)) {
     unlink($path.$file);
 }

Well, if its there still any confusion you just need to change the operator from the first line of code.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser4951View Question on Stackoverflow
Solution 1 - PhpbuschtoensView Answer on Stackoverflow
Solution 2 - PhpStefanie Janine StöltingView Answer on Stackoverflow
Solution 3 - PhpMaksim.TView Answer on Stackoverflow
Solution 4 - PhpLeonView Answer on Stackoverflow
Solution 5 - PhpLachitView Answer on Stackoverflow
Solution 6 - PhpNiet the Dark AbsolView Answer on Stackoverflow
Solution 7 - Phpuser3657553View Answer on Stackoverflow
Solution 8 - PhpJohn CarterView Answer on Stackoverflow
Solution 9 - PhpSimbiatView Answer on Stackoverflow
Solution 10 - PhpMiguelView Answer on Stackoverflow
Solution 11 - PhpShahzeb AhmedView Answer on Stackoverflow