backup_path = __DIR__ . '/../backups'; if (!file_exists($this->backup_path)) { mkdir($this->backup_path, 0755, true); } $this->db_config = [ 'host' => DB_SERVER, 'user' => DB_USERNAME, 'pass' => DB_PASSWORD, 'name' => DB_NAME ]; } public function createBackup() { $timestamp = date('Y-m-d_H-i-s'); $backup_file = $this->backup_path . '/backup_' . $timestamp; // Backup database $this->backupDatabase($backup_file . '.sql'); // Backup files $this->backupFiles($backup_file . '.zip'); // Clean old backups (keep last 5) $this->cleanOldBackups(); return true; } private function backupDatabase($file) { $command = sprintf( 'mysqldump --host=%s --user=%s --password=%s %s > %s', escapeshellarg($this->db_config['host']), escapeshellarg($this->db_config['user']), escapeshellarg($this->db_config['pass']), escapeshellarg($this->db_config['name']), escapeshellarg($file) ); exec($command, $output, $return_var); if ($return_var !== 0) { throw new Exception('Database backup failed'); } } private function backupFiles($file) { $root_path = __DIR__ . '/..'; $exclude_dirs = ['backups', 'cache', 'logs', 'vendor']; $zip = new ZipArchive(); if ($zip->open($file, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) { throw new Exception('Cannot create zip file'); } $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($root_path), RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($files as $name => $file) { if ($file->isDir()) { continue; } $filePath = $file->getRealPath(); $relativePath = substr($filePath, strlen($root_path) + 1); // Skip excluded directories $skip = false; foreach ($exclude_dirs as $exclude) { if (strpos($relativePath, $exclude . '/') === 0) { $skip = true; break; } } if (!$skip) { $zip->addFile($filePath, $relativePath); } } $zip->close(); } private function cleanOldBackups($keep = 5) { $files = glob($this->backup_path . '/*'); usort($files, function($a, $b) { return filemtime($b) - filemtime($a); }); if (count($files) > $keep) { for ($i = $keep; $i < count($files); $i++) { unlink($files[$i]); } } } public function restore($backup_date) { $sql_file = $this->backup_path . '/backup_' . $backup_date . '.sql'; $zip_file = $this->backup_path . '/backup_' . $backup_date . '.zip'; if (!file_exists($sql_file) || !file_exists($zip_file)) { throw new Exception('Backup files not found'); } // Restore database $command = sprintf( 'mysql --host=%s --user=%s --password=%s %s < %s', escapeshellarg($this->db_config['host']), escapeshellarg($this->db_config['user']), escapeshellarg($this->db_config['pass']), escapeshellarg($this->db_config['name']), escapeshellarg($sql_file) ); exec($command, $output, $return_var); if ($return_var !== 0) { throw new Exception('Database restore failed'); } // Restore files $zip = new ZipArchive(); if ($zip->open($zip_file) !== true) { throw new Exception('Cannot open backup archive'); } $zip->extractTo(__DIR__ . '/..'); $zip->close(); return true; } }