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('&', '&amp;', $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());
	
}
?>