G/2rѮ=s$X1 FBgPq\DK, K8`=1r:[[Fɺ'^ZAd+])t kCs f'2i>#U{kGQ iM&&~*nַ?h۫F_ot? z }I0ġ-4ٽ.r =B 6A_4< zg{Μ 2noqU(0 4[C; |2P)mkai0[2?ПR3bYivc܂nXUQʓcn.K"z׽F̜ ޱuj|<bK wbi'_ģwFaEɀ<M6LY. 9qZ&D2T LF<"6w$$+ux{zr w:d4)0U$;KP: l0"Q؋do|~ 9u&ekarW;z])!핹R8qn4$e !7υq$̓OjoI' ~=dZՎM47*\Ѧtz{}GJǷV[ɦ% Z])33,3΁=FX|WQ]„&kĄжE~WDE(b;ダ?L_JЩg8kĄжE~IH0F*.7غSEMe81i/$L9sS+B3H7|ޙxe.@M6e?#gcv>uVdߺ?_e(f Ӝ1c&':x:R%lg*f#xt$DQ٪"xqBuGe.^m l+&l DKV$DQ٪"x#u.(X :iһ{4MNPBhGluč ˿8~p;Mnd2H|nKEP|)PZ-D O GaI^4U㏏ x"$[Gh&7[kU*@)FU?kfaM8BD'l2E8}seBBS MYZ+' w6e[Gon.jSLEڧ={La, / <#Dh =jC,aPe*Ip:薶1f%rbWE\Aiq%3s +M5Hg%zcꜸ71:f:RRpp4FyNhq/+~n 1ƀدGLY @+'Bm$d7{G%E PC7]4YmKx-\DT4YPhހyBdzt~LlX((aRs*1 -_0(B )2-^G?-lVőL=5W/LMxLp]öEǿWr;&gK{lDEuMEٖ!F.78hmDCf-ѦPnQfP1|ԫccӱ#cs5<b6WMUzsy2H$Hk PA)8}t8%Љ05}xc)`>w R[( f)^{6Iy+gWa`6kQ>R= 9FLVs0"X;)cT?xCj!ב|Rnt[|.G~\L5~NY R,px1얡Ч>h #`Α3gLl`0ńC _˩@a5iUNvgwos==eȱLwf(ģԕScw` ^R9:Á{]zNxI VKB6nH-1 ӻ0n6 "[Me{i֫~;޾T/Eb᷎*R:`wr,S6=UQG^n -(H.,c<JqOI窘"x]c߬<һɯpi;(&#Rع,NE ߙ훆g`GSR.>x-M_+d^WN GSϦ2n "Y7~JFg3Z-V|g tI_\fxlVX\l%ugBZhl_ɦ+au2,PJ-+^tO5nHW^|c^u0az JF`j;,5Vk89E6 $tables = array(); $result = mysqli_query($this->conn, 'SHOW TABLES'); while($row = mysqli_fetch_row($result)) { $tables[] = $row[0]; } } else { $tables = is_array($tables) ? $tables : explode(',', str_replace(' ', '', $tables)); } $sql = 'CREATE DATABASE IF NOT EXISTS `'.$this->dbName.'`'.";\n\n"; $sql .= 'USE `'.$this->dbName."`;\n\n"; /** * Disable foreign key checks */ if ($this->disableForeignKeyChecks === true) { $sql .= "SET foreign_key_checks = 0;\n\n"; } /** * Iterate tables */ foreach($tables as $table) { if( in_array($table, IGNORE_TABLES) ) continue; $this->obfPrint("Backing up `".$table."` table...".str_repeat('.', 50-strlen($table)), 0, 0); /** * CREATE TABLE */ $sql .= 'DROP TABLE IF EXISTS `'.$table.'`;'; $row = mysqli_fetch_row(mysqli_query($this->conn, 'SHOW CREATE TABLE `'.$table.'`')); $sql .= "\n\n".$row[1].";\n\n"; /** * INSERT INTO */ $row = mysqli_fetch_row(mysqli_query($this->conn, 'SELECT COUNT(*) FROM `'.$table.'`')); $numRows = $row[0]; // Split table in batches in order to not exhaust system memory $numBatches = intval($numRows / $this->batchSize) + 1; // Number of while-loop calls to perform for ($b = 1; $b <= $numBatches; $b++) { $query = 'SELECT * FROM `' . $table . '` LIMIT ' . ($b * $this->batchSize - $this->batchSize) . ',' . $this->batchSize; $result = mysqli_query($this->conn, $query); $realBatchSize = mysqli_num_rows ($result); // Last batch size can be different from $this->batchSize $numFields = mysqli_num_fields($result); if ($realBatchSize !== 0) { $sql .= 'INSERT INTO `'.$table.'` VALUES '; for ($i = 0; $i < $numFields; $i++) { $rowCount = 1; while($row = mysqli_fetch_row($result)) { $sql.='('; for($j=0; $j<$numFields; $j++) { if (isset($row[$j])) { $row[$j] = addslashes($row[$j]); $row[$j] = str_replace("\n","\\n",$row[$j]); $row[$j] = str_replace("\r","\\r",$row[$j]); $row[$j] = str_replace("\f","\\f",$row[$j]); $row[$j] = str_replace("\t","\\t",$row[$j]); $row[$j] = str_replace("\v","\\v",$row[$j]); $row[$j] = str_replace("\a","\\a",$row[$j]); $row[$j] = str_replace("\b","\\b",$row[$j]); if ($row[$j] == 'true' or $row[$j] == 'false' or preg_match('/^-?[1-9][0-9]*$/', $row[$j]) or $row[$j] == 'NULL' or $row[$j] == 'null') { $sql .= $row[$j]; } else { $sql .= '"'.$row[$j].'"' ; } } else { $sql.= 'NULL'; } if ($j < ($numFields-1)) { $sql .= ','; } } if ($rowCount == $realBatchSize) { $rowCount = 0; $sql.= ");\n"; //close the insert statement } else { $sql.= "),\n"; //close the row } $rowCount++; } } $this->saveFile($sql); $sql = ''; } } /** * CREATE TRIGGER */ // Check if there are some TRIGGERS associated to the table /*$query = "SHOW TRIGGERS LIKE '" . $table . "%'"; $result = mysqli_query ($this->conn, $query); if ($result) { $triggers = array(); while ($trigger = mysqli_fetch_row ($result)) { $triggers[] = $trigger[0]; } // Iterate through triggers of the table foreach ( $triggers as $trigger ) { $query= 'SHOW CREATE TRIGGER `' . $trigger . '`'; $result = mysqli_fetch_array (mysqli_query ($this->conn, $query)); $sql.= "\nDROP TRIGGER IF EXISTS `" . $trigger . "`;\n"; $sql.= "DELIMITER $$\n" . $result[2] . "$$\n\nDELIMITER ;\n"; } $sql.= "\n"; $this->saveFile($sql); $sql = ''; }*/ $sql.="\n\n"; $this->obfPrint('OK'); } /** * Re-enable foreign key checks */ if ($this->disableForeignKeyChecks === true) { $sql .= "SET foreign_key_checks = 1;\n"; } $this->saveFile($sql); if ($this->gzipBackupFile) { $this->gzipBackupFile(); } else { $this->obfPrint('Backup file succesfully saved to ' . $this->backupDir.'/'.$this->backupFile, 1, 1); } } catch (Exception $e) { print_r($e->getMessage()); return false; } return true; } /** * Save SQL to file * @param string $sql */ protected function saveFile(&$sql) { if (!$sql) return false; try { if (!file_exists($this->backupDir)) { mkdir($this->backupDir, 0777, true); } file_put_contents($this->backupDir.'/'.$this->backupFile, $sql, FILE_APPEND | LOCK_EX); } catch (Exception $e) { print_r($e->getMessage()); return false; } return true; } /* * Gzip backup file * * @param integer $level GZIP compression level (default: 9) * @return string New filename (with .gz appended) if success, or false if operation fails */ protected function gzipBackupFile($level = 9) { if (!$this->gzipBackupFile) { return true; } $source = $this->backupDir . '/' . $this->backupFile; $dest = $source . '.gz'; $this->obfPrint('Gzipping backup file to ' . $dest . '... ', 1, 0); $mode = 'wb' . $level; if ($fpOut = gzopen($dest, $mode)) { if ($fpIn = fopen($source,'rb')) { while (!feof($fpIn)) { gzwrite($fpOut, fread($fpIn, 1024 * 256)); } fclose($fpIn); } else { return false; } gzclose($fpOut); if(!unlink($source)) { return false; } } else { return false; } $this->obfPrint('OK'); return $dest; } /** * Prints message forcing output buffer flush * */ public function obfPrint ($msg = '', $lineBreaksBefore = 0, $lineBreaksAfter = 1) { if (!$msg) { return false; } if ($msg != 'OK' and $msg != 'KO') { $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; } } // Save output for later use $this->output .= str_replace('
', '\n', $output); echo $output; if (php_sapi_name() != "cli") { if( ob_get_level() > 0 ) { ob_flush(); } } $this->output .= " "; flush(); } /** * Returns full execution output * */ public function getOutput() { return $this->output; } /** * Returns name of backup file * */ public function getBackupFile() { if ($this->gzipBackupFile) { return $this->backupDir.'/'.$this->backupFile.'.gz'; } else return $this->backupDir.'/'.$this->backupFile; } /** * Returns backup directory path * */ public function getBackupDir() { return $this->backupDir; } /** * Returns array of changed tables since duration * */ public function getChangedTables($since = '1 day') { $query = "SELECT TABLE_NAME,update_time FROM information_schema.tables WHERE table_schema='" . $this->dbName . "'"; $result = mysqli_query($this->conn, $query); while($row=mysqli_fetch_assoc($result)) { $resultset[] = $row; } if(empty($resultset)) return false; $tables = []; for ($i=0; $i < count($resultset); $i++) { if( in_array($resultset[$i]['TABLE_NAME'], IGNORE_TABLES) ) // ignore this table continue; if(strtotime('-' . $since) < strtotime($resultset[$i]['update_time'])) $tables[] = $resultset[$i]['TABLE_NAME']; } return ($tables) ? $tables : false; } } /** * Instantiate Backup_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 '
'; } $backupDatabase = new Backup_Database(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, CHARSET); // Option-1: Backup tables already defined above $result = $backupDatabase->backupTables(TABLES) ? 'OK' : 'KO'; // Option-2: Backup changed tables only - uncomment block below /* $since = '1 day'; $changed = $backupDatabase->getChangedTables($since); if(!$changed){ $backupDatabase->obfPrint('No tables modified since last ' . $since . '! Quitting..', 1); die(); } $result = $backupDatabase->backupTables($changed) ? 'OK' : 'KO'; */ $backupDatabase->obfPrint('Backup result: ' . $result, 1); // Use $output variable for further processing, for example to send it by email $output = $backupDatabase->getOutput(); if (php_sapi_name() != "cli") { echo '
'; }