Dès la création d'un site internet, il faut penser à une solution de sauvegarde et de restauration rapide des données, généralement contenus dans la base de données, mais aussi des fichiers HTML, PHP, .htaccess et autres qui constituent la colonne vertébrale de votre site. En effet, la totalité de votre travail pourrait être anéantie en l'espace de quelques secondes si une panne de disque dur intervenait sur le serveur, si vous faisiez une erreur de manipulation ou encore si un pirate informatique arrivait à prendre le contrôle de votre serveur et détruisait votre site internet.
<?php
/*******************************************************************
Classe permettant la connexion propre à MySQLi
********************************************************************/
class connexion extends mysqli {
public function __construct($host, $user, $pass, $db) {
parent::__construct($host, $user, $pass, $db);
if (mysqli_connect_error()) {
die('Erreur de connexion (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
}
}
}
/******************************************************************
Supprime la table de l'ancienne sauvegarde et la re-crée (une table par site)
*******************************************************************/
function createTable($site,$connectVars){
$db = new connexion($connectVars['host'], $connectVars['user'], $connectVars['password'], $connectVars['db']);
$db->set_charset("utf8");
$txt1 = "DROP TABLE IF EXISTS `backup_".$site."`;";
$txt2 = "CREATE TABLE IF NOT EXISTS `backup_".$site."` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`path` varchar(256) COLLATE utf8_unicode_ci NOT NULL,
`content` longblob NOT NULL,
`permissions` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`owner_id` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`owner_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`group_id` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`group_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(256) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;";
$db->query($txt1);
$query = $db->query($txt2);
$db->close();
if($query) return(true); else return(false);
}
?>
<?php
/******************************************************************
Explore et enregistre chaque répertoire et sous-répertoire
Convertit chaque fichier en binaire et l'enregistre dans la BDD
*******************************************************************/
function recur_dir($dir,$exclude=array(),$site,$baseDir,$db) {
$dirlist = opendir($dir);
while ($file = readdir ($dirlist)){ // explore le répertoire
if (!in_array($file,array('.','..','.DS_Store'))){ // Vérifie que le fichier doit bien être sauvegardé
$newpath = $dir.'/'.$file;
$permissions = substr(decoct(fileperms($newpath)),-4);
$ownerIud = fileowner($newpath);
$ownerName = posix_getpwuid($ownerIud);
$groupIud = filegroup ($newpath);
$groupInfo = posix_getgrgid($groupIud);
$groupName = $groupInfo['name'];
if (is_dir($newpath)){ // Si le fichier est un répertoire, enregistre dans la BDD et explore les sous-répertoires
$txt = "INSERT INTO `".$site."` (id,type,path,permissions,owner_id,owner_name,group_id,group_name,name,content) VALUES (0,'DIR','".str_replace($baseDir.'/','',$newpath)."','".$permissions."','".$ownerIud."','".$ownerName['name']."','".$groupIud."','".$groupName."','".$file."','')";
$db->query($txt);
if(!in_array(str_replace($baseDir.'/','',$dir.'/'.$file),$exclude)) recur_dir($newpath,$exclude,$site,$baseDir,$db);
}
else { // Convertit les fichiers en binaire et les enregistre dans la base de données
$FileContent = $db->real_escape_string(bin2hex(file_get_contents($newpath)));
$txt = "INSERT INTO `".$site."` (id,type,path,permissions,owner_id,owner_name,group_id,group_name,name,content) VALUES (0,'FILE','".str_replace($baseDir.'/','',$newpath)."','".$permissions."','".$ownerIud."','".$ownerName['name']."','".$groupIud."','".$groupName."','".$file."',x'".$FileContent."')";
$db->query($txt);
}
}
}
closedir($dirlist);
}
?>
<?php
/******************************************************************
Envoie un mail de reporting au format UTF-8
*******************************************************************/
function envoyer($objet,$content){
global $mailVars;
$to = $mailVars['to'];
$headers = 'From: '.$mailVars['fromName'].' <'.$mailVars['fromAddr'].'>'."\n";
$headers .= 'Reply-to: '.$to."\n";
$headers .= 'Return-Path: '.$to."\n";
$headers .= 'Message-ID: <'.time().'.'.$to.'>'."\n";
$headers .= 'X-Mailer: PHP v'.phpversion()."\n";
$headers .= 'X-Sender: '.$to."\n";
$headers .= 'X-auth-smtp-user: '.$to."\n";
$headers .= 'X-abuse-contact: '.$mailVars['AbuseAddr']."\n";
$headers .= 'MIME-version: 1.0'."\n";
$headers .= 'Content-Type: text/plain; charset=UTF-8'."\n";
$headers .= 'Content-Transfer-Encoding: 8bit'."\n"."\n";
$subject = '=?UTF-8?q?'.str_replace('%', '=', rawurlencode($objet)).'?=';
$body = $content."\n";
mail($to, $subject, $body, $headers);
}
/******************************************************************
Retourne la durée en H:m:s entre 2 microtime
*******************************************************************/
function duree($debut,$fin){
$difference = round($fin - $debut,2);
$heures = floor($difference/3600);
$minutes = floor(($difference - ($heures * 3600)) /60);
$secondes = $difference -(($minutes*60) + ($heures * 3600));
$duree = ($heures>0?$heures.' heure'.($heures>1?'s ':' '):' ').($minutes>0?$minutes.' min. ':'').$secondes.' secondes';
return $duree;
}
?>
<?php
include( __DIR__ .'/functions.php');
include( __DIR__ .'/config.php'); // Fichier à renseigner avec vos paramètres
/****************************************************************************
Copie des fichiers dans la base
*****************************************************************************/
$content = 'Début du backup'."\n\n";
foreach($configuration as $site => $v)
{
$debInter = microtime(true);
if(false !== createTable($site,$v['dbConnect']))
{
$db = new connexion($v['dbConnect']['host'], $v['dbConnect']['user'], $v['dbConnect']['password'], $v['dbConnect']['db']);
$db->set_charset("utf8");
$content .= 'Table backup_'.$site.' créée. Le backup de ce site peut commencer.'."\n";
recur_dir($v['siteRoot'],$v['ignore'],'backup_'.$site,$v['siteRoot'],$db);
$finInter = microtime(true);
$content .= 'Mise à jour de la table backup_'.$site.' terminée en '.duree($debInter,$finInter)."\n\n";
$db->close();
}
else $content .= 'Impossible de créer la table backup_'.$site.'. Le backup de ce site est abandonné.'."\n\n";
}
/****************************************************************************
Fin du script - génération et envoi du rapport
*****************************************************************************/
$fin = microtime(true);
$content .= "Script terminé - Temps d'exécution : ".duree($debut,$fin)."\n";
$subject = 'Backup de mes sites';
envoyer($subject,$content);
?>