picture
juin 12, 2005 PHP 34 Commentaires

Script PHP de sauvegarde automatique des bases de données

… avec auto-effacement des sauvegardes de plus de 7 jours love

Ce script me permet une sauvegarde quotidienne de mes bases directement sur le FTP.
Un fichier .sql est créé et stocké automatiquement tous les soirs, auto-effaçable au bout d’une semaine.
Je complète ce dispositif par une sauvegarde hebdomadaire de l’ensemble des fichiers du serveur: rien n’est trop sà»r pour ces petites choses, un plantage de serveur ou un hack sont si vite arrivés … :C

Le script :

<?php
// création d’une fonction comportant les identifiants de connexion au FTP :

function mysql_structure() {
$host = ‘mon_serveur’;
$user = ‘mon_login’;
$pass = ‘mot_de_passe’;
$base = ‘nom_de_la_base’;

// création d’un fichier affichant en boucle le contenu des tuples de la base :

mysql_connect($host, $user, $pass);
mysql_select_db($base);
$tables = mysql_list_tables($base);
while ($donnees = mysql_fetch_array($tables))
{
$table = $donnees[0];
$res = mysql_query("SHOW CREATE TABLE $table");
if ($res)
{
$insertions = "";
$tableau = mysql_fetch_array($res);
$tableau[1] .= ";";
$dumpsql[] = str_replace(" ", "", $tableau[1]);
$req_table = mysql_query("SELECT * FROM $table");
$nbr_champs = mysql_num_fields($req_table);
while ($ligne = mysql_fetch_array($req_table))
{
$insertions .= "INSERT INTO $table VALUES(";
for ($i=0; $i<=$nbr_champs-1; $i++)
{
$insertions .= "’" . mysql_real_escape_string($ligne[$i]) . "’, ";
}
$insertions = substr($insertions, 0, -2);
$insertions .= "); ";
}
if ($insertions != "")
{
$dumpsql[] = $insertions;
}
}
}
return implode("
", $dumpsql);
}

// creation d’une fonction file_put_content si le script est en PHP4 :

if(!function_exists(‘file_put_contents’)) {
function file_put_contents($filename, $data, $file_append = false) {
$fp = fopen($filename, (!$file_append ? ‘w+’ : ‘a+’));
if(!$fp) {
trigger_error(‘file_put_contents ne peut pas écrire dans le fichier.’, E_USER_ERROR);
return;
}
fputs($fp, $data);
fclose($fp);
}
}

// création du fichier de dump sur le même niveau que ce fichier dump.php

file_put_contents("sqldump_".date("d-n-Y").".sql", mysql_structure());

// effacement du fichier precedant (créé 7 jours plus tot)
$time_old = getdate(mktime()-(7*24*3600));
$an = $time_old['year'];
$mois = $time_old['mon'];
$jour = $time_old['mday'];

// formatage des jours à 1 chiffre

for($k=1; $k<10; $k++)
{
if ($jour==$k)
{
$jour=’0′.$jour;
}
}

$date_old=$jour.’-’.$mois.’-’.$an;
$file_old="sqldump_".$date_old.".sql";
unlink($file_old);
?>

Derniere étape : utilisation des services gratuits de WEBCRON pour lancer ce script tous les jours.

Ce site génial (et gratuit) vous permet de déclancher à distance, et à heures fixes, votre fichier dump.php …

Mode d’emploi très intuitif, vous commencez par créer un compte qui vous permettra de lancer 6 scripts pour 6 bases des données MySQL (si vous en avez plus… creez plusieurs comptes !)

Pour lancer, par exemple, tous les soirs à 20h un fichier dump.php stocké dans un dossier « dump », vous aurez ceci :

et encore dans l’interface « mes tâches » :

Vous aurez donc « in fine » dans le dossier « dump » : 7 fichiers de sauvegarde (les 7 derniers jours) + le fichier de script :

Génial, non ?! :))

34 Responses to “Script PHP de sauvegarde automatique des bases de données”

34 Commentaires

  1. christian dit :

    bonjour

    Votre script n’interesse seulement
    ma BDD etant un peut lourd ,ca ne marche pas.
    connaissez le moyen de sauvegardé des base tres lourde ,ou
    peut t-on sauvegarde "table par table"

    Merci

  2. Web Tolosa dit :

    Tu peux toujours tenter de prolonger la duree du script en mettant un petit htaccess sur la racine de ton site (sans les ===) :
    ===============================
    AuthUserFile /var/alternc/html/w/webtolosa/livrereligieux/.htpasswd
    AuthName « Protection_admin »
    AuthType Basic
    require valid-user
    php_value max_execution_time 420
    ===============================

    Si tu es sur un serveur Apache, et si l’admin a autorisé les htaccess, tu auras 420 secondes d’exécution pour tes scripts PHP , c’est en général suffisant…

  3. Mixo dit :

    Ce script est vraiment génial mais j’obtiens un message d’erreur lorsque je l’exécute
    voici le message en question :
    Warning: unlink(sqldump_09-8-2007.sql) [function.unlink]: No such file or directory in /home.xxx/xxxxx/www/backup.php on line 86

  4. webtolosa dit :

    c’est normal mixo : ce message te dit que tu ne peux pas effacer les sauvegardes des jours précédents… parceque les fichiers n’existent pas encore puisque tu viens de le mettre en ligne.

    la solution consiste à dire au script de ne pas effacer les fichiers des 7 jours précédents s’ils n’existent pas pour une raison ou pour une autre (ton cron peut ne pas marcher par exemple):

    if(isset($file_old) {
    unlink($file_old);
    }

  5. Prach dit :

    bonjour, j’ai un message d’erreur lorsque j’exécute ce script :
    Call to undefined function: file_put_contents()

    que faut il modifier ? :|

  6. webtolosa dit :

    Bonjour prach, comme il est dit dans le script, la fonction file_pu_contents() est une fonction PHP5. Vérifie la version PHP de ton serveur avec un phpinfo() Donc si le fichier du script est hébergé sur un serveur qui roule sur PHP4, il te faut « créer » cette fonction, et tu as le code ci-dessus, regarde la partie commentée « // creation d’une fonction file_put_content si le script est en PHP4 : »

  7. sikko dit :

    merci pour ton script qui fonctionne très bien.
    J’ai pour ma part ajouté un petit bout de code qui permet de gzipper le tout, et de supprimer le fichier .sql:

    /******************************************
    * COMPRESSION D’UN FICHIER DU SERVEUR
    *
    * – lecture des données originales
    * – compression avec gzencode()
    * – écriture des données compressées
    * – affichage du gain de la compression
    *
    * 29 mai 2003, Hugo ETIEVANT
    * http://cyberzoide.developpez.com/php4/
    *******************************************/

    // nom et chemin du fichier à compresser
    $filename = "sqldump_".date("d-n-Y").".sql";

    // ouverture du fichier à compresser
    if($fp = fopen($filename, "rb")) {

    // lecture du contenu
    $size1 = filesize($filename);
    $data = fread($fp, $size1);
    // fermeture
    fclose($fp);

    // compression des données
    $gzdata = gzencode($data, 9);

    // ouverture et création du fichier compressé
    if($fp = fopen($filename.’.gz’, ‘wb’)) {

    // écriture des données compressées
    fwrite($fp, $gzdata);
    // fermeture
    fclose($fp);

    // calcul gain de la compression
    $size2 = filesize($filename.’.gz’);
    $diff = $size1-$size2;
    $pc = round($diff/$size1*100, 2);
    echo "Gain de la compression : $diff octets soit $pc %.";
    $fichier_a_supp = "sqldump_".date("d-n-Y").".sql";
    unlink($fichier_a_supp);
    } else {
    echo "Impossible d’ouvrir $filename.gz en écriture.";
    }

    } else {
    echo "Impossible d’ouvrir $filename en lecture.";
    }

  8. webtolosa dit :

    bien vu et merci de ton partage :)

  9. Oxydoreduction dit :

    Génial merci :bravo:
    Par contre je suis passé par le web cron de Saint Pitoune la Creuviere parceque j’avais besoin d’une fréquence de lancement plus élevée qu’un par jour. Là, j’ai programmé mon script 2 fois par jour nickel.

  10. webjo dit :

    Bonjour,

    Je suis chez 1&1 et j’ai 4 BD à sauvegarder est ce que cela est possible avec votre script ? Merci

    Cordialement

  11. Adnane dit :

    :)) :)) :)) :)) :)) :)) :)) :bravo: :bravo: :bravo: :bravo:

  12. @webjo dit :

    Desolé de decouvrir tard ton post … si tu repassais il est bien évidemment possible de mettre 4 crons … soit 4 fichiers éxécutables PHP (un par base) et 4 cons pour les lancer !

    Tu peux aussi mettre le même code 4 fois de suite sur un seul fichier, ça se lancera en suite => bref pas de problème :)

  13. Jean dit :

    bonjour,

    merci pour ce super script et la bonne idée d’utiliser webcron.

    Est ce que cela serait compliqué de transmettre automatiquement le fichier gzipé par mail ? (ma base est petite donc ça serait pas mal dans ma situation).

  14. webtolosa dit :

    non, pas vraiment…
    Mais il faut que tu installes et utilises par exemple la librairie zip.lib.php :
    http://www.phpfrance.com/tutoria...

    Ensuite tu n’as qu’à récupérer le fichier truc.sql que tu as déposé sur ton serveur, tu le zippes (regardes le lien ci-dessus), et tu l’envoies avec une bête fonction mail()
    Tout doit tenir sur le même fichier cron :)

    Tu as même un autre exemple de zip ici

  15. jean dit :

    merci. ça marche très bien.

  16. JO dit :

    Je n’arrive pas à me connacter à ma base :

    Peux-tu donner un exemple de valeurs stp
    $host = ‘mon_serveur’;
    $user = ‘mon_login’;
    $pass = ‘mot_de_passe’;
    $base = ‘nom_de_la_base’;

  17. webtolosa dit :

    @JO

    difficile de te donner un exemple, il faut que tu aies les paramètres de connexion à TA base (ton hébergeur a dû te les donner)
    Si tu veux un exemple bidon, ça donne un truc du genre :
    $host = ’108.92.45.85′;
    $user = ‘toto’;
    $pass = ’1234′;
    $base = ‘login_db’;

  18. weshcoast dit :

    Bonjour en executant ce script j’obtient l’erreur :

    Fatal error: Maximum execution time of 6 seconds exceeded in /www/weshcoast/forum/dmp/dump.php on line 35

    cette ligne correspond a :

    }
    $insertions = substr($insertions, 0, -2);
    $insertions .= "); ";

    Il s’agit surement du erreur due au temsp d’execution mais je suis chez olympe network je ne sais pas comment le réglé ( htaccess n’a pas fonctionné ) …

    Ceci est assez urgent , merci de votre aide

  19. max dit :

    Excellent !!!
    Fonctionne impeccablement pour plusieurs bdd en même temps…
    MERCI BEAUCOUP !
    :))

  20. dav dit :

    j’ai essayé ce script avec succès, malheureusement mes tables dont les noms ne sont composées que de chiffres ne sont pas sauvegardées.
    après divers essais je me suis rendu compte que mon problème venait de la requête "SHOW CREATE TABLE $table" quoi échappe les noms composés de chiffres.
    quelqu’un voit-il une solution à mon problème?
    merci pour vos réponses

    ps: encore bravo pour ce script :bravo:

  21. dav dit :

    :""( help :""(

  22. xav dit :

    Bravo pour ce script, par contre j’ai un petit souci avec les caractères accentués qui sont mal interprétés lors de l’export dans le fichier SQL. Est-ce que vous auriez une idée pour rétablir le bug ?!
    D’avance merci

  23. Xav dit :

    J’ai trouvé si ca peut aider d’autres personnes :

    Ajouter : mysql_query("SET NAMES UTF8");


    mysql_connect($host, $user, $pass);
    mysql_select_db($base);

    mysql_query("SET NAMES UTF8");

    $tables = mysql_list_tables($base);

  24. Nico dit :

    :)) vraiment très pratique, et également merci pour l’astuce des caractères accentués !

  25. ed130 dit :

    Excellent script, j’ai simplement mis en commentaire la ligne ‘// unlink($file_old);
    ‘ afin d’éviter un retour erreur du serveur car j’utilise un hébergement mutualisé chez OVH et je crains un retour erreur du serveur. Pour info, leur interface de gestion Manager permet de programmer des taches cron à la fréquence que l’on souhaite. Je repasserai cette ligne en écriture dans 7 jours.

    Merci !

  26. Gégé dit :

    Bonjour,

    J’ai recopié intégralement le script, l’ai sauvegardé après avoir indiqué les paramètres de connexion à la base. Je l’ai transféré sur mon mutualisé 1and1, puis je l’ai appelé dans le navigateur.

    J’obtiens l’erreur suivante (pas très explicite, j’en conviens) :
    Error 500 – Internal server error
    Un problème inattendu est survenu.
    Veuillez réessayer ultérieurement.

    Si quelqu’un avait une idée géniale …

  27. Gégé dit :

    Pour info le serveur est en PHP 4.4.9.

  28. ReDiX dit :

    Regarde si tu as un .htaccess, si c’est le cas déplace ton script dans un dossier dans ce fichiers la

  29. Nico dit :

    Bonjour,

    Lorsque j’exécute le script, cela me retourne l’erreur suivante:

    Fatal error: Maximum execution time of 300 seconds exceeded in /home/httpd/vhosts/club205gti.fr/httpdocs/forum09/dump/dump.php on line 35

    Ma base doit être trop grosse…
    Auriez vous une solution??? (et même l’idéal serait de sauvegarder table par table…).
    Merci!!!
    ;)

  30. Webtolosa dit :

    effectivement ta base doit être trop un peu obèse…
    La seule solution (à moins de purger un peu la base du forum ;))est d’augmenter le temps d’exécution des scripts sur le serveur avec un htaccess de type "php_value max_execution_time 420" si ton hébergeur accepte… regarde ici il y a le mode d’emploi :http://www.webtolosa.com/index.p...

  31. Noliv dit :

    MAGNIFIQUE
    avec l’option zip à la fin que du bonheur
    thanks

  32. Mc dit :

    Même problème sur 1and1 avec une erreur 500.
    Et je n’ai pas très bien compris la solution proposée plus haut :|

  33. webtolosa@Mc dit :

    en principe cela signifie que ton serveur 1&1 n’accepte pas une des fonctions ou une extension que tu y mets.
    Souvent il s’agit des fichiers .htaccess que les serveurs mutualisés n’acceptent pas tous donc si tu as mis un fichier .htaccess pour augmenter le temps d’exécution de ton script, enlève le et regarde si cela marche.

    Au passage, si je peux me permettre … 1&1 ce n’est vraiment pas top question hebergement. Contacte moi par e-mail (voir menu de gauche contact > webtolosa) si tu veux des tuyaux.

  34. cocotte dit :

    j’ai trouvé!
    l’expédition de la sauvegarde par mail marche impec!
    :))
    ~:(
    il me reste plus qu’a tester CRON mais ça je sais que c’est fastoch’

    merci et encore bravo!!!

Commentaire

Name

Mail (ne sera pas publié)

Website

Laisser ces deux champs tels quels :