%s 2>&1', escapeshellarg(DB_HOST), escapeshellarg(DB_USER), escapeshellarg(DB_PASS), escapeshellarg(DB_NAME), escapeshellarg($filepath) ); $output = []; $return_var = null; exec($command, $output, $return_var); if ($return_var !== 0) { $error_msg = implode("\n", $output); throw new Exception("Database backup failed with exit code {$return_var}: " . $error_msg); } // Automatic cleanup: keep only the last 5 backups cleanup_backups($backups_dir, 5); return [ 'filename' => $filename, 'filepath' => $filepath, 'size' => filesize($filepath) ]; } /** * Cleanup old backups, keeping only the most recent $keep_count files. * * @param string $backups_dir Path to backups directory * @param int $keep_count Number of backups to retain */ function cleanup_backups($backups_dir, $keep_count = 5) { $files = glob("{$backups_dir}/backup_*.sql"); // Sort by modification time (newest first) usort($files, function($a, $b) { return filemtime($b) - filemtime($a); }); // Remove files beyond the keep count if (count($files) > $keep_count) { $files_to_remove = array_slice($files, $keep_count); foreach ($files_to_remove as $file) { if (is_file($file)) { unlink($file); } } } }