I have asked the same question before and I found this solution :
if ($handle = opendir('/path/to/your/folder'))
{
$files = array();
while (false !== ($file = readdir($handle)))
{
if (!is_dir($file))
{
// You'll want to check the return value here rather than just blindly adding to the array
$files[$file] = filemtime($file);
}
}
// Now sort by timestamp (just an integer) from oldest to newest
asort($files, SORT_NUMERIC);
// Loop over all but the 5 newest files and delete them
// Only need the array keys (filenames) since we don't care about timestamps now as the array will be in order
$files = array_keys($files);
for ($i = 0; $i < (count($files) - 5); $i++)
{
// You'll probably want to check the return value of this too
unlink($files[$i]);
}
}
And I have edited to fit my needs like this:
public function cleanup() {
$files = glob("$this->location/*.sql");
$count = count($files);
if($count >= $this->maxbackups) {
$timestamps = array();
foreach( $files as $value) {
$timestamps[$value] = filemtime($value);
}
asort($timestamps, SORT_NUMERIC);
$timestamps = array_keys($timestamps);
for ($i = 0; $i < (count($timestamps) - 1); $i++) {
unlink($timestamps[$i]);
}
return $this->message->error(false,'Backups successfuly cleaned');
} else {
return $this->message->error(true,'Backups could not be cleaned');
}
}
But the problem is that it deletes all files but the first, not the last created, why is that ?
Use for ($i = 1; $i < (count($timestamps)); $i++)
. That could make it work.
I think you can make it more effective and reduce complexity. (Requires only one loop, not two, neither sorting is required)
$files = glob("$this->location/*.sql");
if( count( $files) < 2){
return 0; // No files deleted
}
$file = array_shift( $files);
$mTime = filemtime( $file);
foreach( $files as $currFile){
$currTime = filemtime( $currFile);
if( $currTime > $mTime){
unlink( $file);
$file = $currFile;
$mTime = $currTime;
} else {
unlink( $currFile);
}
}
You were on the right track with using glob
for simplification, but instead of manually counting or whatnot, try:
$files = glob("dir/*.sql");
$files = array_combine($files, array_map("filemtime", $files));
arsort($files); // orders by mtime, newest files first
$files = array_keys($files);
$files = array_slice($files, 5); // removes the first 5
array_map("unlink", $files); // delete remaining list
But you could of course use a manual foreach
in place of the array_map
.