* @version 1.0 */ /** * Define database parameters here */ define("DB_USER", 'your_username'); define("DB_PASSWORD", 'your_password'); define("DB_NAME", 'your_db_name'); define("DB_HOST", 'localhost'); define("BACKUP_DIR", 'myphp-backup-files'); // Comment this line to use same script's directory ('.') define("BACKUP_FILE", 'myphp-backup-your_db_name-20181022_164459.sql.gz'); // Script will autodetect if backup file is gzipped based on .gz extension define("CHARSET", 'utf8'); define("DISABLE_FOREIGN_KEY_CHECKS", true); // Set to true if you are having foreign key constraint fails /** * The Restore_Database class */ class Restore_Database { /** * Host where the database is located */ var $host; /** * Username used to connect to database */ var $username; /** * Password used to connect to database */ var $passwd; /** * Database to backup */ var $dbName; /** * Database charset */ var $charset; /** * Database connection */ var $conn; /** * Disable foreign key checks */ var $disableForeignKeyChecks; /** * Constructor initializes database */ function __construct($host, $username, $passwd, $dbName, $charset = 'utf8') { $this->host = $host; $this->username = $username; $this->passwd = $passwd; $this->dbName = $dbName; $this->charset = $charset; $this->disableForeignKeyChecks = defined('DISABLE_FOREIGN_KEY_CHECKS') ? DISABLE_FOREIGN_KEY_CHECKS : true; $this->conn = $this->initializeDatabase(); $this->backupDir = defined('BACKUP_DIR') ? BACKUP_DIR : '.'; $this->backupFile = defined('BACKUP_FILE') ? BACKUP_FILE : null; } /** * Destructor re-enables foreign key checks */ function __destructor() { /** * Re-enable foreign key checks */ if ($this->disableForeignKeyChecks === true) { mysqli_query($this->conn, 'SET foreign_key_checks = 1'); } } protected function initializeDatabase() { try { $conn = mysqli_connect($this->host, $this->username, $this->passwd, $this->dbName); if (mysqli_connect_errno()) { throw new Exception('ERROR connecting database: ' . mysqli_connect_error()); die(); } if (!mysqli_set_charset($conn, $this->charset)) { mysqli_query($conn, 'SET NAMES '.$this->charset); } /** * Disable foreign key checks */ if ($this->disableForeignKeyChecks === true) { mysqli_query($conn, 'SET foreign_key_checks = 0'); } } catch (Exception $e) { print_r($e->getMessage()); die(); } return $conn; } /** * Backup the whole database or just some tables * Use '*' for whole database or 'table1 table2 table3...' * @param string $tables */ public function restoreDb() { try { $sql = ''; $multiLineComment = false; $backupDir = $this->backupDir; $backupFile = $this->backupFile; /** * Gunzip file if gzipped */ $backupFileIsGzipped = substr($backupFile, -3, 3) == '.gz' ? true : false; if ($backupFileIsGzipped) { if (!$backupFile = $this->gunzipBackupFile()) { throw new Exception("ERROR: couldn't gunzip backup file " . $backupDir . '/' . $backupFile); } } /** * Read backup file line by line */ $handle = fopen($backupDir . '/' . $backupFile, "r"); if ($handle) { while (($line = fgets($handle)) !== false) { $line = ltrim(rtrim($line)); if (strlen($line) > 1) { // avoid blank lines $lineIsComment = false; if (preg_match('/^\/\*/', $line)) { $multiLineComment = true; $lineIsComment = true; } if ($multiLineComment or preg_match('/^\/\//', $line)) { $lineIsComment = true; } if (!$lineIsComment) { $sql .= $line; if (preg_match('/;$/', $line)) { // execute query if(mysqli_query($this->conn, $sql)) { if (preg_match('/^CREATE TABLE `([^`]+)`/i', $sql, $tableName)) { $this->obfPrint("Table succesfully created: `" . $tableName[1] . "`"); } $sql = ''; } else { throw new Exception("ERROR: SQL execution error: " . mysqli_error($this->conn)); } } } else if (preg_match('/\*\/$/', $line)) { $multiLineComment = false; } } } fclose($handle); } else { throw new Exception("ERROR: couldn't open backup file " . $backupDir . '/' . $backupFile); } } catch (Exception $e) { print_r($e->getMessage()); return false; } if ($backupFileIsGzipped) { unlink($backupDir . '/' . $backupFile); } return true; } /* * Gunzip backup file * * @return string New filename (without .gz appended and without backup directory) if success, or false if operation fails */ protected function gunzipBackupFile() { // Raising this value may increase performance $bufferSize = 4096; // read 4kb at a time $error = false; $source = $this->backupDir . '/' . $this->backupFile; $dest = $this->backupDir . '/' . date("Ymd_His", time()) . '_' . substr($this->backupFile, 0, -3); $this->obfPrint('Gunzipping backup file ' . $source . '... ', 1, 1); // Remove $dest file if exists if (file_exists($dest)) { if (!unlink($dest)) { return false; } } // Open gzipped and destination files in binary mode if (!$srcFile = gzopen($this->backupDir . '/' . $this->backupFile, 'rb')) { return false; } if (!$dstFile = fopen($dest, 'wb')) { return false; } while (!gzeof($srcFile)) { // Read buffer-size bytes // Both fwrite and gzread are binary-safe if(!fwrite($dstFile, gzread($srcFile, $bufferSize))) { return false; } } fclose($dstFile); gzclose($srcFile); // Return backup filename excluding backup directory return str_replace($this->backupDir . '/', '', $dest); } /** * Prints message forcing output buffer flush * */ public function obfPrint ($msg = '', $lineBreaksBefore = 0, $lineBreaksAfter = 1) { if (!$msg) { return false; } $msg = date("Y-m-d H:i:s") . ' - ' . $msg; $output = ''; if (php_sapi_name() != "cli") { $lineBreak = "
"; } else { $lineBreak = "\n"; } if ($lineBreaksBefore > 0) { for ($i = 1; $i <= $lineBreaksBefore; $i++) { $output .= $lineBreak; } } $output .= $msg; if ($lineBreaksAfter > 0) { for ($i = 1; $i <= $lineBreaksAfter; $i++) { $output .= $lineBreak; } } if (php_sapi_name() == "cli") { $output .= "\n"; } echo $output; if (php_sapi_name() != "cli") { ob_flush(); } flush(); } } /** * Instantiate Restore_Database and perform backup */ // Report all errors error_reporting(E_ALL); // Set script max execution time set_time_limit(900); // 15 minutes if (php_sapi_name() != "cli") { echo '
'; } $restoreDatabase = new Restore_Database(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); $result = $restoreDatabase->restoreDb(BACKUP_DIR, BACKUP_FILE) ? 'OK' : 'KO'; $restoreDatabase->obfPrint("Restoration result: ".$result, 1); if (php_sapi_name() != "cli") { echo '
'; }