Classe de backup de BDD (MySQL)
Par Nicolas SUPRIN, vendredi 2 juin 2006 à 21:55 | PHP | #43 | rss
Voici une classe PHP5 permettant de réaliser un backup d'une base de données de type MySQL4, mais pas encore totalement de MySQL5 (vue, procédures...), et d'effectuer l'import.
Pré-requis
- PHP5
- Vous devez utiliser le package PEAR DB.
La classe
Il y a un exemple d'appel a la fin du fichier, voici le maintenant le code :
<?php /** * @desc Classe de backup Mysql * @author NSN <nicolas.suprin@cactuscrew.com> * @package * @copyright Fri Jun 02 10:32:22 CEST 2006 * @version 1.0 * @since 1.0 */ class Backup { /** * @var DB $O_connection Connection MySQL * @access private */ private $O_connection; /** * @var string $S_backpup Contenu du backup * @access private */ private $S_backup; /** * @desc Constructeur * @author NSN <nicolas.suprin@cactuscrew.com> * @param * @return void * @see * @copyright 2005 * @version 1.0 * @since 1.0 */ public function __construct($O_connection) { if (!DB::isConnection($O_connection)) { throw new Exception('Vous devez utiliser un objet de type PEAR DB'); } if (DB::isError($O_connection)) { throw new Exception('Impossible de se connecter à la base de données: '.$O_connection->getDebugInfo()); } $this->O_connection = $O_connection; $this->_init(); } /** * @desc Initialisation * @author NSN <nicolas.suprin@cactuscrew.com> * @param * @return void * @see * @copyright 2005 * @version 1.0 * @since 1.0 */ private function _init() { $this->S_backup = ''; $this->_writeBackup('/*********************************'); $this->_writeBackup(' * Backup du '.date('Y/m/d H:i:s'). ' *'); $this->_writeBackup(' *********************************/'); $this->_writeBackup(); } /** * @desc ecrit une nouvelle ligne dans le backup * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @param string $S_ligne ligne à inserer * @return void * @copyright Fri Jun 02 10:54:41 CEST 2006 * @version 1.0 * @since 1.0 */ private function _writeBackup($S_ligne = '') { $this->S_backup .= $S_ligne."\n"; } /** * @desc show databases; * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @return array * @copyright Fri Jun 02 10:37:43 CEST 2006 * @version 1.0 * @since 1.0 */ public function exportDataBases() { $S_query = $this->O_connection->getSpecialQuery('databases'); $A_dataBases = $this->O_connection->getCol($S_query); if (DB::isError($A_dataBases)) { throw new Exception('Impossible de recuperer la lise des bases: '.$A_databases->getDebugInfo()); } if (!is_array($A_dataBases)) { throw new Exception('La liste de base est corrompue'); } // --- pour chaque BDD foreach ($A_dataBases as $S_dataBaseName) { $this->_writeBackup('/* Base de données '.$S_dataBaseName.' */'); $this->_writeBackup('CREATE DATABASE IF NOT EXISTS `'.$S_dataBaseName.'`;'); // --- recupere la liste des tables $A_tables = $this->exportTables($S_dataBaseName); } return $A_databases; } /** * @desc show tables; * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @return array * @copyright Fri Jun 02 10:37:43 CEST 2006 * @version 1.0 * @since 1.0 */ public function exportTables($S_dataBase) { // --- se place dans la bonne bdd $this->useBdd($S_dataBase); $this->_writeBackup('USE `'.$S_dataBase.'`;'); $this->_writeBackup(); // --- recupere la liste des tables $S_query = $this->O_connection->getSpecialQuery('tables'); $A_tables = $this->O_connection->getCol($S_query); if (DB::isError($A_tables)) { throw new Exception('Impossible de recuperer la lise des tables: '.$A_tables->getDebugInfo()); } if (!is_array($A_tables)) { throw new Exception('La liste de tables est corrompue'); } // --- pour chaque table foreach ($A_tables as $S_tableName) { $this->exportThisTable($S_tableName); } return $A_tables; } /** * @desc modifie la connexion, pour aller dans une autre bdd * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @param string $S_dataBase nom de la base de données * @return void * @copyright Fri Jun 02 16:20:08 CEST 2006 * @version 1.0 * @since 1.0 */ private function useBdd($S_dataBase) { // --- recupere le dsn actuel $A_dsn = $this->O_connection->dsn; // --- modifie la base $A_dsn{'database'} = $S_dataBase; // --- reconnecte $this->O_connection->connect($A_dsn); // --- cas des connexion un peu persistantes $O_use = $this->O_connection->query('USE `'.$S_dataBase.'`;'); if (DB::isError($O_use)) { throw new Exception('Impossible d\acceder a la base de données: '.$O_use->getDebugInfo()); } } /** * @desc crée la description de la structure de table * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @param string $S_tableName nom de la table * @return void * @see * @copyright Fri Jun 02 11:17:21 CEST 2006 * @version 1.0 * @since 1.0 */ public function exportThisTable($S_tableName) { $this->_writeBackup('/* '.$S_tableName.' */'); $this->_writeBackup('DROP TABLE IF EXISTS `'.$S_tableName.'`;'); $this->_writeBackup(); $S_query = 'SHOW CREATE TABLE `'.$S_tableName.'`;'; $A_detail = $this->O_connection->getRow($S_query); if (DB::isError($A_detail)) { throw new Exception('Impossible de recuperer les detail de la table: '.$A_detail->getDebugInfo()); } $this->_writeBackup($A_detail[1].';'); $this->_writeBackup(); $this->exportTableData($S_tableName); $this->_writeBackup(); $this->_writeBackup(); } /** * @desc données d'une table * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @param $S_table * @return void * @copyright Fri Jun 02 12:17:12 CEST 2006 * @version 1.0 * @since 1.0 */ public function exportTableData($S_table) { // --- recupere la description $S_query = 'DESCRIBE `'.$S_table.'`'; $A_desc = $this->O_connection->getAll($S_query); if (DB::isError($A_desc)) { throw new Exception('Impossible de recuperer les detail de la table:'.$A_desc); } // --- pour cahque colonne $S_cols = ''; foreach ($A_desc as $S_col) { $S_cols .= '`'.$S_col[0].'`, '; } $S_cols = substr($S_cols, 0, strlen($S_cols) - 2); // --- exporte les resultast $S_sql = ' SELECT '.$S_cols.' FROM `'.$S_table.'`'; $A_values = $this->O_connection->getAll($S_sql); if (DB::isError($A_values)) { throw new Exception('Impossible de recuperer les valeurs de la table'.$A_values->getDebugInfo()); } // --- si on a des enregisteremnt if (sizeof($A_values) > 0) { $this->_writeBackup('INSERT INTO `'.$S_table.'` ('.$S_cols.') VALUES '); $S_values = ''; // --- pour chaque ligne foreach ($A_values as $A_ssValues) { $S_values .= '('; $i = 0; $S_ssvalues = ''; // --- pour chque colonne foreach ($A_desc as $S_value) { $S_val = addslashes($A_ssValues[$i++]); $S_val = str_replace("\n", '\n', $S_val); $S_val = str_replace("\r", '\r', $S_val); $S_val = str_replace('&', '&', $S_val); $S_ssvalues .= '\''.$S_val.'\', '; } $S_ssvalues = substr($S_ssvalues, 0, strlen($S_ssvalues) - 2); $S_values .= $S_ssvalues."),\n"; } $S_values = substr($S_values, 0, strlen($S_values) - 2).';'; $this->_writeBackup($S_values); } } /** * @desc toFile * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @param String $S_fileName chemin du fichier * @return void * @copyright Fri Jun 02 13:51:03 CEST 2006 * @version 1.0 * @since 1.0 */ public function toFile($S_fileName) { file_put_contents($S_fileName, $this->S_backup); } /** * @desc separe les requetes SQL * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @param string $S_sql contenu sql * @return void * @see * @copyright Tue May 23 08:09:05 CEST 2006 * @version 1.0 * @since 1.0 */ public static function extractSqlQueries($S_sql) { $A_return = array(); if (is_string($S_sql)) { // --- on extrait tout les lignes $A_sqlTmp = explode("\n", $S_sql); $S_sql = ''; $A_sql = array(); // --- pour chauqe ligne foreach ($A_sqlTmp as $S_sqlTmp) { // on vire les espaces inutiles $S_sql .= trim($S_sqlTmp)."\n"; // On recupere la longeur de la requete $I_lg = strlen($S_sql); // position du ; $I_pos = strrpos($S_sql, ';'); // si on fini la ligne par un ; if ($I_pos !== false && $I_pos >= $I_lg - 2) { // on ajoute le sql dans le tableau des requets $A_return[] = $S_sql; // et on remet le cach à zero $S_sql = ''; } } } // s'il nous reste des trucs dans le cache... if (strlen($S_sql) > 5) { $A_return[] = $S_sql; } return $A_return; } /** * @desc execute une requete sql * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @param string $S_sql requete a executer * @return void * @see * @copyright Wed May 10 14:36:24 CEST 2006 * @version 1.0 * @since 1.0 */ public static function executeQuery($S_sql, $O_db) { $B_return = true; // --- attention, si la requete est USE bdd... if (stripos('USE ') != false) { // --- il faut changer la base de donnée de connection /** * @todo recuperer le nom de la base de données */ // $this->useBdd(...); } $O_result = $O_db->query($S_query); if (DB::isError($O_result)) { // --- si on a fait un alter table, que sa génére un erreur, // on ne lance pas d'exception if (stripos('ALTER ') != false) { throw new Exception($O_result->getDebugInfo() ); } else { $B_return = $O_result->getDebugInfo(); } } return $B_return; } /** * @desc Execute plusieurs requetes * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @return void * @copyright Fri Jun 02 16:00:58 CEST 2006 * @version 1.0 * @since 1.0 */ public function executeMultiQueries($S_queries) { // --- Extrait les requete de la chaine $A_queries = $this->extractSqlQueries($S_queries); if (!is_array($A_queries)) { throw new Exception('Erreur, pas de requete trouvée'); } // --- pour chaque requete foreach ($A_queries as $S_sql) { // --- execution $this->executeQuery($S_sql, $this->O_connection); } } /** * @desc execute le rollback * @author NSN <nicolas.suprin@cactuscrew.com> * @access public * @return void * @copyright Fri Jun 02 16:03:55 CEST 2006 * @version 1.0 * @since 1.0 */ public function executeBackup($S_sql = null) { if (!is_null($S_sql)) { $this->S_backup = $S_sql; } $this->executeMultiQueries($this->S_backup); } /** ACCESSEURS */ public function getBackup() { return $this->S_backup; } public function setBackup($S_backup) { $this->S_backup = $S_backup; } } require_once $_SERVER['DOCUMENT_ROOT'].'/globalConf.php'; require_once 'DB.php'; try { $O_db = DB::connect('mysqli://login:pass@server.com/bdd'); $O_backup = new Backup($O_db); // --- Exporte toutes les base de données du serveur // $O_backup->showDataBases(); // --- Exporte toutes les tables de la BDD maBdd $O_backup->exportTables('maBdd'); // --- Exporte toutes les inforamtions de la table maTable // $O_backup->exportThisTable('ma'); // --- on exporte tout sa dans un fichier $O_backup->toFile('monBackup.sql'); // --- detruit l'objet unset($O_backup); // --- on crée un nouvel objetc $O_import = new Backup($dbwibux); // --- on charge depuis le fichier de tout à l'heure $O_import->setBackup(file_get_contents('monBackup.sql')); // --- et zou, on execute $O_import->executeBackup($S_backup); } catch (Exception $O_fault) { print_rn($O_fault->getMessage()); } ?>





Aucun commentaire pour le moment.
Aucun trackback.
Pour faire un trackback sur ce billet : http://www.blog.cactuscrew.com/tb.php?id=43&chk=hsmcw7