删除文件夹中的所有文件,但最后一次删除?

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.