Synchronisation de 2 BDD MySQL en PHP

Signaler
Messages postés
18
Date d'inscription
mardi 16 juin 2020
Statut
Membre
Dernière intervention
20 novembre 2020
-
Messages postés
30256
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 novembre 2020
-
Bonjour, j'ai besoin d'exporter ma base de données MySQL fonctionnant sur un Serveur Local Windows Server 2012 R2, l'export devrait se faire vers un Serveur En Ligne hébergé chez IONOS et pour laquelle la base de données possède la même structure que celle En Local mais de nom différent. Comment m'y prendre ?

Dans la seconde étape, il sera question que j'écrive un autre script PHP sur le Serveur IONOS à distance qui tourne sur LINUX, lequel script PHP va se charger d'importer ce fichier exporté depuis mon Serveur Local Windows Server ... Alors, ma question : Comment m'y prendre pour Réussir le tout ?

4 réponses

Messages postés
30256
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 novembre 2020
2 998
Bonjour,

Pour des bases mysql ... il suffit de faire un DUMP de celle que tu veux sauvegarder, puis importer ce DUMP dans ta nouvelle BDD

https://phoenixnap.com/kb/how-to-backup-restore-a-mysql-database

https://www.sqlshack.com/how-to-backup-and-restore-mysql-databases-using-the-mysqldump-command/

.
Messages postés
18
Date d'inscription
mardi 16 juin 2020
Statut
Membre
Dernière intervention
20 novembre 2020

Je suis tout à fait d'accord avec Vous sur ce point (c'est-à-dire "En Ligne de Commande"), seulement que dans mon cas le problème c'est d'écrire un script PHP qui devrait faire d'abord l'EXPORT de toute ma Base De Données en Local, puis se connecter au Serveur En Ligne MySQL de IONOS pour faire le sens contraire, c'est-à-dire l'IMPORT de ladite Base MySQL qui a la même structure ... Comment écrire ce script PHP ??? Parce que je ne suis pas certain que la syntaxe du Code qui fonctionne En Ligne de Commande est la même que celle à écrire dans un script PHP !!! C'est 2 environnements totalement différent. En plus, ce script doit être automatisé, je devrais créer une tâche CRON sur mon Windows Server pour qu'il le fasse automatiquement, bien sûr à des intervalles réguliers, genre toutes les 3 heures du temps (à 6h30, puis à 9h30, puis encore à 12h30, 15h30, 18h30, 20h30 et il devrait s'arrêter à 23h30 par exemple ...).
Voilà c'est exactement en détails de çà qu'il s'agit en définitive.
Messages postés
30256
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 novembre 2020
2 998

puis se connecter au Serveur En Ligne MySQL de IONOS

Déjà .. ce point la risque de bloquer....

L'accès à distance de ta BDD ( sur un serveur IONOS) est, le plus souvent impossible.



C'est 2 environnements totalement différent. En plus, ce script doit être automatisé, je devrais créer une tâche CRON sur mon Windows Server pour qu'il le fasse automatiquement, bien sûr à des intervalles réguliers, genre toutes les 3 heures du temps (à 6h30, puis à 9h30, puis encore à 12h30, 15h30, 18h30, 20h30 et il devrait s'arrêter à 23h30 par exemple ...).

Via cette Tache CRON, génère un DUMP de ta BDD ..puis envois en FTP, le DUMP sur ton server IONOS
Puis, sur ton serveur IONOS, faire également une tache CRON qui chargerait ce DUMP dans ta bdd.
Messages postés
18
Date d'inscription
mardi 16 juin 2020
Statut
Membre
Dernière intervention
20 novembre 2020

Jai l'envie de dire que la syntaxe de mysqldump n'est adaptée qu'ene ligne de commande et non dans un script PHP, car voilà que j'ai mis ce script puis paramétré une tâche planifiée sous Windows Server 2012 R2 (tâche CRON) et en allant dans le système, le Planificateur de tâches Windows m'indique un message : "L'opération a été annulée par l'utilisateur. (0x800704C7) ...
Voici ce qua été le contenu de mon script PHP que j'ai logé dans un dossier de mon application :
//Entrez ici les informations de votre base de données et le nom du fichier de sauvegarde.
$mysqlDatabaseName ='database';
$mysqlUserName ='xxxxxxxxxxxxxx';
$mysqlPassword ='xxxxxxxxxxxxxx';
$mysqlHostName ='adresse ip';
$mysqlExportPath ='fichier-export.sql';

//Veuillez ne pas modifier les points suivants
//Exportation de la base de données et résultat
$command='mysqldump --opt -h' .$mysqlHostName .' -u' .$mysqlUserName .' -p' .$mysqlPassword .' ' .$mysqlDatabaseName .' > ' .$mysqlExportPath;
exec($command,$output=array(),$worked);
switch($worked){
case 0:
echo 'La base de données <b>' .$mysqlDatabaseName .'</b> a été stockée avec succès dans le chemin suivant '.getcwd().'/' .$mysqlExportPath .'</b>';
break;
case 1:
echo 'Une erreur s est produite lors de l exportation de <b>' .$mysqlDatabaseName .'</b> vers'.getcwd().'/' .$mysqlExportPath .'</b>';
break;
case 2:
echo 'Une erreur d exportation s est produite, veuillez vérifier les informations suivantes : <br/><br/><table><tr><td>MySQL Database Name:</td><td><b>' .$mysqlDatabaseName .'</b></td></tr><tr><td>MySQL User Name:</td><td><b>' .$mysqlUserName .'</b></td></tr><tr><td>MySQL Password:</td><td><b>NOTSHOWN</b></td></tr><tr><td>MySQL Host Name:</td><td><b>' .$mysqlHostName .'</b></td></tr></table>';
break;
}


Je ne vois pas dans mon Code là où le bas blaisse ...
Messages postés
30256
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 novembre 2020
2 998
Vu le message d'erreur, il s'agit d'avantage d'un pb d'exécution du script depuis la planificateur de tâches.
Est-ce que au moins, tu as testé le script directement.... (sans passer par le planificateur ) ?
Et puis, comment as tu créés ta tâche planifiée ?
Avec quel user as tu programmé cette tâche ?
En général, on exécute le script PHP depuis un fichier bat .. et c'est ce bat qui est lancé par windows... et il faut que le PATH vers l'exe de PHP soit configuré dans le système
(mais là, on sort du cadre de ce forum qui ne traite que du langage php... si tu as des soucis pour planifier la tâche, faudra certainement poser une question dans le forum windows.)

A noter que tu pourrais aussi générer ton dump en powershell ...
par exemple
https://gallery.technet.microsoft.com/scriptcenter/PowerShell-to-perform-a687f0df
Messages postés
18
Date d'inscription
mardi 16 juin 2020
Statut
Membre
Dernière intervention
20 novembre 2020
>
Messages postés
30256
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 novembre 2020

En suivant votre Lien-ci https://gallery.technet.microsoft.com/scriptcenter/PowerShell-to-perform-a687f0df, je n'ai pas vu Comment ils expliquent la génération du DUMP en PowerShell ...
Pour répondre à vos questions, je dirai :
1/- Comment vais-je tester le script directement sans passer par le planificateur ?
2/- Pour la création de ma tâche planifiée, j'ai tout simplement suivi ce tuto via ce Lien-ci https://www.pcastuces.com/pratique/astuces/4245.htm
3/- De quel User faites-vous allusion ? J'ai mis en début de mon Script PHP le Nom de l'Utilisateur que j'avais créé dans phpMyAdmin, ainsi que son Mot De Passe, comme ceci :
$mysqlDatabaseName ='nom de la base de données';
$mysqlUserName ='nom de l'utilisateur de la base de données';
$mysqlPassword ='mot de de l'utilisateur de la base de données';
$mysqlHostName ='adresse ip du serveur';
$mysqlExportPath ='fichier-export.sql';


4/- Comment on exécute un script PHP depuis un fichier bat ?
Messages postés
30256
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 novembre 2020
2 998 >
Messages postés
18
Date d'inscription
mardi 16 juin 2020
Statut
Membre
Dernière intervention
20 novembre 2020

Comment, fais-tu, pour exécuter un script PHP en ligne de commande ?
si tu es capable de répondre à cette question, alors tu sais comment faire depuis un fichier BAT....
Messages postés
18
Date d'inscription
mardi 16 juin 2020
Statut
Membre
Dernière intervention
20 novembre 2020

En revanche, toujours dans ma quête de solutions, j'avais trouvé un Script sur GitHub, lequel vous fait l'Export d'une Base de données via PHP et la sauvegarde via FTP, mais je ne l'ai pas encore essayé. Voici intégralement le Script PHP organisé sous forme de 2 fichiers :

A/ - Script PHP n° 1 :
/**
* DatabaseExport is a tool to export database via PHP and store it via FTP
*
* Copyright (c) 2011 Tomas Pavlatka (http://tomas.pavlatka.cz)
*
* @package DatabaseExport
*/

header("content-type: text/plain; charset=utf-8");

// Require classes.
require_once 'classes/Database.php';

// Export params.
$params = array(
    'database' => array(
	    'db_host'       => 'localhost',
	    'db_name'       => 'db_name',
	    'db_user'       => 'root',
	    'db_password'   => '',
	    'db_charset'    => 'utf8'),
    'ftp' => array(
        'ftp_server'    => '',
        'ftp_username'  => '',
        'ftp_password'  => '',
        'ftp_folder'    => ''
    ),
    'export' => array(
        'export_folder' => './backups/',
        'export_zip'    => 'bzip2',
    )
);

// Export database..
$dbObj = new PTX_Database($params['database']);
$dbObj->connect();

$dbTables = array();
if($dbObj->mysqlListTables()) {
	while($table = $dbObj->mysqlFetchArray()){
		$dbTables[] = (string)$table[0];	
	}
}
$exportedData = $dbObj->dbExport($dbTables);
	
// Save a file.
$fileName = $params['database']['db_name'].'-'.date('YmdHis').'.sql';
$filePath = $params['export']['export_folder'].$fileName;

if($params['export']['export_zip'] == 'bzip2') {
    $fileName .= '.bz2';
    $filePath .= '.bz2';
	$bz = bzopen($filePath, "w");
    bzwrite($bz, $exportedData);
    bzclose($bz);
} else {
	$fopen = fopen($filePath,'w+');
	fwrite($fopen,$exportedData);
	fclose($fopen);	
}

// Copy to FTP.
$ftpConnect = ftp_connect($params['ftp']['ftp_server']);
$ftpLogin = ftp_login($ftpConnect, $params['ftp']['ftp_username'], $params['ftp']['ftp_password']);
if($ftpLogin) {
    // Upload a file
    $destination = $params['ftp']['ftp_folder'].$fileName;
    $upload = ftp_put($ftpConnect, $destination, $filePath, FTP_BINARY); 	
}
ftp_close($ftpConnect); 


B/ - Script PHP n° 2 :
/**
* DatabaseExport is a tool to export database via PHP and store it via FTP
*
* Copyright (c) 2011 Tomas Pavlatka (http://tomas.pavlatka.cz)
*
* @package DatabaseExport
*/

class PTX_Database {
	
	/*
	 * Holds actual connection.
	 */
	private $_dbConnect;
	
    /*
     * Private variable holding option for class.
     */
	private $_options = array(
		'db_host'       => '',
	    'db_name'       => '',
	    'db_user'       => '',
	    'db_password'   => '',
	    'db_charset'    => 'utf-8');

	private $_selectQuery;
	
	/**
	 * Construct.
	 * 
	 * constructor of the class
	 * @param array $options - parameters for class
	 */
	public function __construct(array $options = array()) {
		$this->_options = array_merge($this->_options,$options);
	}
	
	/**
	 * Connect.
	 * 
	 * connects to the database.
	 */
	public function connect(){
       
		if(!$this->_dbConnect = @mysql_connect($this->_options['db_host'],$this->_options['db_user'],$this->_options['db_password'])){
            exit('Unable to connect to database');
        }
        if(!@mysql_select_db($this->_options['db_name'], $this->_dbConnect)) {
            exit(sprintf('Unable to connect to database %s',$this->_options['db_name']));
        }
        
        // Set charset.
        mysql_query("SET CHARACTER SET ".$this->_options['db_charset']);
	}
	
	/**
	 * Export.
	 * 
	 * exports database into text
	 * @param array $tables - list of the table
	 * @return exported data
	 */
    public function dbExport(array $tables) {
        $exportData = null;
        
    	foreach($tables as $table) {
            $exportData .= $this->_createExportHeader($table);
            $exportData .= $this->_getExportData($table);
        }
        
        return $exportData;
    }
    
    /**
     * Mysql Fetch Array.
     * 
     * fetch array from database.
     */
    public function mysqlFetchArray(){
        return @mysql_fetch_array($this->_selectQuery);
    }
    
    /**
     * Mysql Fetch Assoc.
     * 
     * fetch array assoc from database.
     */
    public function mysqlFetchAssoc(){
        return @mysql_fetch_assoc($this->_selectQuery);
    }
	
    /**
     * Mysql List Tables.
     * 
     * mysql_query to find all tables in database.
     * @return true | false
     */
    public function mysqlListTables(){
        if(!$this->_selectQuery = @mysql_query("SHOW TABLES FROM ".$this->_options['db_name'],$this->_dbConnect)) {
            return false;
        } else {
            return true;	
        }
    }
    
    /**
     * Create export header (Private).
     * 
     * creates header for export
     * @param $table - name of a table
     * @return header
     */
    private function _createExportHeader($table) {
    	// Fields.
    	$fields = array();
    	$query = mysql_query("DESCRIBE `{$table}`",$this->_dbConnect);
        while($field = mysql_fetch_assoc($query)) {
              $fields[] = $field;
        }
        
        // Indexes.
        $indexes = array();
        $query = mysql_query("SHOW INDEXES FROM `{$table}`");
        while($index = mysql_fetch_assoc($query)) {
            if(isset($indexes[$index['Key_name']])) {
            	$indexes[$index['Key_name']][] = $index;
            } else {
            	$indexes[$index['Key_name']] = array($index);
            }
        }
        
        // Table status.
        $query = mysql_query("SHOW TABLE STATUS WHERE `Name` = '{$table}'");
        $status = mysql_fetch_assoc($query);
        
        // Table header.
        $header  = "DROP TABLE IF EXISTS `{$table}`;\n";
        $header .= "CREATE TABLE `{$table}` (\n";
        foreach($fields as $key => $values) {
        	$header .= "\t`".$values['Field']."` ".$values['Type'];
        	if($values['Null'] == 'NO') {
        		$header .= " not null";
        	} else {
        		$header .= " null";
        	}
        	
        	// TODO: What about MySQL constants ?
        	if(!empty($values['Default'])) {
        		if($values['Default'] == 'CURRENT_TIMESTAMP') {
        			$header .= " default ".$values['Default'];
        		} else {
                    $header .= " default '".$values['Default']."'";
        		}
        	}
        	if(!empty($values['Extra'])) {
        		$header .= " ".$values['Extra'];
        	}
        	
        	$header .= ",\n";
        }
        
        $countIndexes = count($indexes);
        $counter = 1;
        foreach($indexes as $indexKey => $indexValeus) {
        	if($indexKey == 'PRIMARY') {
        		$header .= "\tPRIMARY KEY (";
                    $keyString = null;
        		    foreach($indexValeus as $indKey => $indValues) {
                        $keyString .= "`".$indValues['Column_name']."`,";
                    }
                    $header .= substr($keyString,0,-1);
        	} else {
        		$header .= "\tKEY `".$indexKey."` (";
                    $keyString = null;
                    foreach($indexValeus as $indKey => $indValues) {
                    	
                        $keyString .= "`".$indValues['Column_name']."`";
                        
                        if(!empty($indValues['Sub_part'])) {
                        	$keyString .= ' ('.$indValues['Sub_part'].')';
                        }
                        $keyString .= ",";
                    }
                    $header .= substr($keyString,0,-1);
        	}
        	
        	if($counter++ < $countIndexes) {
        		$header .= "),\n";
        	} else {
        		$header .= ")\n";
        	}
        }
        
        $header .= ") ";
        
        // Additional information.
        $charsetExplode = explode('_',$status['Collation']);
        $status['Charset'] = (isset($charsetExplode[0])) ? $charsetExplode[0] : null;
        $additionalInfo = array('Engine' => 'ENGINE','Auto_increment' => 'AUTO_INCREMENT', 'Charset' => 'CHARSET', 'Collation'  => 'COLLATE');
        foreach($additionalInfo as $key => $name) {
        	if(isset($status[$key]) && !empty($status[$key])) {
        		$header .= $name .'='.$status[$key]." ";
        	} 
        }
        $header .= ";\n\n";
        
        return (string)$header;
    }

    /**
     * Get Export Data (Private).
     * 
     * exports records from database.
     * @param $table - name of a table
     * @return export of records
     */
    private function _getExportData($table) {
        $d = null;
        $data = mysql_query("SELECT * FROM `{$table}` WHERE 1", $this->_dbConnect);
        
        $counter = 1;
        $insertData = null;
        $rowCounter = mysql_num_rows($data);
        if($rowCounter > 0) {
	        while($row = mysql_fetch_assoc($data)) {
	        	if($counter == 1) {
	                $insertData .= "INSERT INTO `{$table}` ";
	                    $columns = array_keys($row);
	                    $columnNames = null;
	                    foreach($columns as $key => $column) {
	                    	$columnsNames .= "`{$column}`,";
	                    }
	                $insertData .= "(".substr($columnsNames,0,-1).") VALUES \n";
	            } 
	            
	            $insertData .= "(";
	            $rowData = null;
	            foreach($row as $column => $value) {
	                $rowData .= "'".mysql_escape_string($value)."',";
	            }
	            $insertData .= substr($rowData,0,-1);
	            
	            if($counter < $rowCounter) {
	                $insertData .= "),\n";
	            } else {
	            	$insertData .= ");\n\n";
	            }
	            
	            // Increase counter;
	            $counter++;
	        }
        }
        
        // Return data.
        return (string)$insertData;
    }
}


Contrairement au premier, ce script me paraît beaucoup plus cohérent ... C'est vrai qu'il est un peu plus long... Qu'en dites-vous ?