Class mysql/sqlite + sauvegarde de bdd + compression zip

Soyez le premier à donner votre avis sur cette source.

Vue 7 227 fois - Téléchargée 372 fois

Description

Après une refonte total du script pour le transformer en class (ca m'as permis de faire ma premiere class au passage), je vous propose une classe gérant 2 type de base : MySQL et SQLite
Cette class permet de se connecter a une base, de faire des requetes, diverses manipulations sur la Bdd et une sauvegarde complete de celle ci.

Je compte bien l'améliorer encore, mais dans l'etat actuelle elle est largement utilisable (à mon avi).

J'attend vos critiques, meme les plus durs.

Source / Exemple :


<?php
/******************

  • class_bdd.php *
  • Auteur : GUEKO *
                                    • /
define('BDD_TYPE_MYSQL', 0); // Base de donnée MySQL define('BDD_TYPE_SQLITE', 1); // Base de donnée SQLite define('BDD_QUERY_TYPE_ASSOC', 1); // MYSQL_ASSOC ou SQLITE_ASSOC define('BDD_QUERY_TYPE_NUM', 2); // MYSQL_NUM ou SQLITE_NUM define('BDD_QUERY_TYPE_BOTH', 3); // MYSQL_BOTH ou SQLITE_BOTH define('BDD_COMP_NONE', 0); // Pas de compression define('BDD_COMP_ZIP', 1); // Compression au format ZIP class Gueko_Bdd { private $dbType = 0; // Type de serveur : MySQL ou SQLite private $dbHost = ''; // Adresse du serveur (SQLite : Emplacement de la base) private $dbName = ''; // Nom de la base (SQLite : inutile) private $dbLogin = ''; // Login de connexion (SQLite : inutile) private $dbPass = ''; // Mot de passe de connexion (SQLite : inutile) private $dbLink = 0; // Identifiant de connexion private $QueryLink = 0; // Référence de la requete private $Err_Bdd_Num = 0; // Numéro de l'erreur private $Err_Bdd_Mes = ''; // Message de l'erreur private $Err_Other = ''; // Message d'erreur personnalisé (hors erreur Bdd) var $NbreQuery = 0; // Nombre de requete effectué function Gueko_Bdd ($dbHost = "", $dbName = "", $dbUser = "", $dbPass = "", $dbType = BDD_TYPE_MYSQL) { $this->dbHost = $dbHost; $this->dbName = $dbName; $this->dbUser = $dbUser; $this->dbPass = $dbPass; $this->dbType = $dbType; } // Se connecte à la base function Connect() { $this->Err_Other = ''; if($this->dbLink === 0) { switch ($this->dbType) { case BDD_TYPE_MYSQL: if(!$this->dbLink = @mysql_connect($this->dbHost, $this->dbUser, $this->dbPass)) { return false; } else { if (!@mysql_select_db($this->dbName, $this->dbLink)) { return false; } } break; case BDD_TYPE_SQLITE: if(!$this->dbLink = @sqlite_open($this->dbHost)) { return false; } break; } } return true; } // Ferme la connexion function Close() { $this->Err_Other = ''; if ($this->dbLink !== 0) { switch ($this->dbType) { case BDD_TYPE_MYSQL: return @mysql_close($this->dbLink); break; case BDD_TYPE_SQLITE: return @sqlite_close($this->dbLink); break; } } } // Exécute une requete function Query($Query) { $this->Err_Other = ''; if ($this->dbLink === 0) { if (!$this->Connect()) { return false; } } switch ($this->dbType) { case BDD_TYPE_MYSQL: if (!$this->QueryLink = @mysql_query($Query, $this->dbLink)) { return false; } break; case BDD_TYPE_SQLITE: if (!$this->QueryLink = @sqlite_query($Query, $this->dbLink)) { return false; } break; } $this->NbreQuery++; return true; } /**
  • Récupère le resultat suivant d'une requête
  • $result_type peut prendre les valeurs :
  • - BDD_QUERY_TYPE_BOTH (défaut), vous récupérerez un tableau contenant des indices associatifs et numériques
  • - BDD_QUERY_TYPE_ASSOC, vous ne récupérerez que les indices associatifs
  • - BDD_QUERY_TYPE_NUM, vous ne récupérerez que les indices numériques
    • /
function Get_Next_Result($result_type = BDD_QUERY_TYPE_BOTH) { $this->Err_Other = ''; switch ($this->dbType) { case BDD_TYPE_MYSQL: $Result = @mysql_fetch_array($this->QueryLink, $result_type); break; case BDD_TYPE_SQLITE: $Result = @sqlite_fetch_array($this->QueryLink, $result_type); break; } if (!$Result) { return false; } return $Result; } // Retourne le numéro de ligne de la dernière ligne insérée function Get_Last_Row_Id() { $this->Err_Other = ''; if ($this->dbLink === 0) { return false; } switch ($this->dbType) { case BDD_TYPE_MYSQL: if (!$Result = @mysql_insert_id($this->dbLink)) { return false; } break; case BDD_TYPE_SQLITE: if (!$Result = @sqlite_last_insert_rowid($this->dbLink)) { return false; } break; } return $Result; } // Retourne le nombre de lignes qui ont été modifiées par la dernière requête function Get_Last_Change() { $this->Err_Other = ''; if ($this->dbLink === 0) { return false; } switch ($this->dbType) { case BDD_TYPE_MYSQL: if (!$Result = @mysql_affected_rows($this->dbLink)) { return false; } break; case BDD_TYPE_SQLITE: if (!$Result = @sqlite_changes($this->dbLink)) { return false; } break; } return $Result; } // Retourne le nombre de lignes d'un résultat function Get_Num_Rows() { $this->Err_Other = ''; if ($this->dbLink === 0) { return false; } switch ($this->dbType) { case BDD_TYPE_MYSQL: if (!$Result = @mysql_num_rows($this->QueryLink)) { return false; } break; case BDD_TYPE_SQLITE: if (!$Result = @sqlite_num_rows($this->QueryLink)) { return false; } break; } return $Result; } // Récupère le message d'erreur function Get_Error() { if ($this->Err_Other === '') { switch ($this->dbType) { case BDD_TYPE_MYSQL: $this->Err_Bdd_Num = @mysql_errno($this->dbLink); $this->Err_Bdd_Mes = @mysql_error($this->dbLink); return $this->Err_Bdd_Num.' : '.$this->Err_Bdd_Mes; break; case BDD_TYPE_SQLITE: $this->Err_Bdd_Num = @sqlite_last_error($this->dbLink); $this->Err_Bdd_Mes = @sqlite_error_string($this->dbLink); return $this->Err_Bdd_Num.' : '.$this->Err_Bdd_Mes; break; } } else { return $this->Err_Other; } } // Récupère la liste complète des tables de la base sous forme d'un tableau function Get_All_Tables() { $this->Err_Other = ''; switch ($this->dbType) { case BDD_TYPE_MYSQL: $Result = @mysql_query('SHOW TABLES', $this->dbLink); $this->NbreQuery++; while ($row = @mysql_fetch_row($Result)) { $Tables[] = $row[0]; } break; case BDD_TYPE_SQLITE: $Result = @sqlite_query('SELECT tbl_name FROM SQLITE_MASTER WHERE type="table"', $this->dbLink); $this->NbreQuery++; while ($row = @sqlite_fetch_array($this->QueryLink, BDD_QUERY_TYPE_NUM)) { $Tables[] = $row[0]; } break; } if (!isset($Tables)) { $this->Err_Other = 'ERREUR : Votre base de donnée ne contient pas de table.'; return false; } return $Tables; } // Protège les caractères spéciaux SQL function Escape_String($String) { $this->Err_Other = ''; if ($this->dbLink === 0) { return false; } switch ($this->dbType) { case BDD_TYPE_MYSQL: if (!$Result = @mysql_real_escape_string($String, $this->dbLink)) { $this->Err_Other = 'Erreur lors du formatage de la chaine de caractère.'; return false; } break; case BDD_TYPE_SQLITE: if (!$Result = @sqlite_escape_string($String)) { $this->Err_Other = 'Erreur lors du formatage de la chaine de caractère.'; return false; } break; } return $Result; } function Optimize_All_Tables() { $this->Err_Other = ''; switch ($this->dbType) { case BDD_TYPE_MYSQL: if ($Tables = $this->Get_All_Tables()) { $First = true; foreach ($Tables as $Table) { if ($First) { $First = false; $Query = "OPTIMIZE TABLE `".$Table."`"; } else { $Query .= ", `".$Table."`"; } } if (!@mysql_query($Query, $this->dbLink)) { return false; } } else { return false; } break; case BDD_TYPE_SQLITE: if (!@sqlite_query('VACUUM', $this->dbLink)) { $this->Err_Other = 'Erreur lors de l\'optimisation des tables.'; return false; } break; } $this->NbreQuery++; return true; } /**
  • Créé un fichier de sauvegarde de la base complète et retourne l'adresse du fichier
  • Pour les bases MySQL : Le format du fichier est écrit en SQL, avec compression si selectionné
  • Pour les bases SQLite : une simple copie du fichier de la base est faite, avec compression si selectionné
  • $Chemin : Chemin de destination de la sauvegarde ("mon/dossier/de/sauvegarde/")
  • $Fichier : Nom du fichier de sauvegarde ("mon_fichier.sql")
  • $Compression : Défini si on compresse ou pas et dans quel format
    • /
function Save_base($Chemin = "", $Fichier = "", $Compression = BDD_COMP_ZIP) { $this->Err_Other = ''; $ExtZip = '.zip'; if ($Chemin !== "") { if (!@mkdir($Chemin,0777,true)) { $this->Err_Other = 'Erreur lors de la création du chemin de sauvegarde : '.$Chemin; return false; } if (substr($Chemin,-1) !== '/') { $Chemin .= '/'; } } switch ($this->dbType) { case BDD_TYPE_MYSQL: if ($Fichier === "") { $Fichier = date('Y-m-d_H\hi\ms',time()).'.sql'; } if (!$Tables = $this->Get_All_Tables()) { $this->Err_Other = 'Il n\'y a pas de tables dans votre base de données.'; return false; } else { $Num_Fich = fopen($Chemin.$Fichier,'w'); foreach($Tables as $Table) { $Result = @mysql_query("SHOW CREATE TABLE `".$Table."`", $this->dbLink); $this->NbreQuery++; $Row = @mysql_fetch_row($Result); fputs($Num_Fich,"DROP TABLE IF EXISTS `".$Table."`;\n"); fputs($Num_Fich,$Row[1].';'."\n\n"); unset($Result, $Row); $Result = @mysql_query("SHOW COLUMNS FROM `".$Table."`", $this->dbLink); $this->NbreQuery++; while ($Row = @mysql_fetch_row($Result)) { $Ligne[] = $Row[0]; } $My_Insert = "INSERT INTO `".$Table."` (`".join("`, `", $Ligne)."`) VALUES\n"; unset($Result, $row, $Ligne); fputs($Num_Fich,$My_Insert); $xx = 0; $Result = mysql_query("SELECT * FROM `".$Table."`", $this->dbLink); $this->NbreQuery++; while ($Row = mysql_fetch_row($Result)) { $Rows[] = $Row; } foreach($Rows as $Row) { if ($xx === 400) { fputs($Num_Fich,join(','."\n",$My_Rows).';'."\n"); fputs($Num_Fich,$My_Insert); $xx=0; unset($My_Rows); } for ($i=0;$i<count($Row);$i++) { $Row[$i] = $this->Escape_String($Row[$i]); if (!$Row[$i]) { $Row[$i] = "NULL"; } elseif (is_numeric($Row[$i])) { $Row[$i] = $Row[$i]; } else { $Row[$i] = "'".$Row[$i]."'"; } } $My_Rows[] = "(".join(",", $Row).")"; $xx++; } fputs($Num_Fich,join(','."\n",$My_Rows).';'."\n\n\n"); unset($My_Insert, $xx, $Result, $Row, $Rows, $My_Rows); } fclose($Num_Fich); if ($Compression === BDD_COMP_ZIP) { include_once 'pclzip.lib.php'; $archive = new PclZip($Chemin.$Fichier.$ExtZip); if (!$archive->create($Chemin.$Fichier)) { $this->Err_Other = 'Erreur lors de la création de l\'archive : '.$Chemin.$Fichier.$ExtZip; return false; } unlink($Chemin.$Fichier); return $Chemin.$Fichier.$ExtZip; } else { return $Chemin.$Fichier; } } break; case BDD_TYPE_SQLITE: if ($Fichier === "") { $Fichier = date('Y-m-d_H\hi\ms',time()).'.sqlite'; } if ($Compression === BDD_COMP_ZIP) { include_once 'pclzip.lib.php'; $this->Close(); $archive = new PclZip($Chemin.$Fichier.$ExtZip); if (!$archive->create($this->dbHost)) { $this->Err_Other = 'Erreur lors de la création de l\'archive : '.$Chemin.$Fichier.$ExtZip; $this->Connect(); return false; } $this->Connect(); return $Chemin.$Fichier.$ExtZip; } else { $this->Optimize_All_Tables(); $this->Close(); if (!@file_exists($Chemin.$Fichier)) { if (!@copy($this->dbHost,$Chemin.$Fichier)) { $this->Err_Other = 'Erreur lors de la sauvegarde du fichier : '.$Chemin.$Fichier; $this->Connect(); return false; } } else { $this->Err_Other = 'Sauvegarde annulée, un fichier du même nom existe déjà.'; $this->Connect(); return false; } $this->Connect(); return $Chemin.$Fichier; } break; } } } ?>

Conclusion :


Le fichier "index.php" est juste là a titre d'exemple d'utilisation de la class.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1
Date d'inscription
lundi 4 décembre 2000
Statut
Membre
Dernière intervention
29 février 2008

mon site utilise la class donc je l'ai naturellement utilisé pour ce fichier.
C'est sur que la ca sert pas des masses.

J'ai bien pris note de vos remarques et je vois pour faire une bonne grosse mise à jour qui va améliorer tout ca.

merci encore
Messages postés
1127
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
Yoman64 à raison sur les différents points qu'il à abordé.
Personnellement j'ajouterai quelques trucs :
Au niveau de la convention de nommage, en général, on met en majuscule les constantes, et en petitGrand les variables. Mais bon, cela n'influe pas sur ton code

Tu travail linéairement. Pourquoi ne pas faire une classe de backUp, où l'on pourrait choisir le type de base de donnée (mysql, pgsql, mssql), le format de sortie (csv, txt, sql, etc), zippé, tarré, etc, et le repertoire d'enregistrement, si on peux le proposer en téléchargement une fois finis, etc.

Actuellement, ton code ne fait qu'un travail linéaire, il n'est donc pas réutilisable de la sorte.
Je compte sur toi pour faire une mise à jour ?
Messages postés
592
Date d'inscription
samedi 19 janvier 2002
Statut
Membre
Dernière intervention
4 décembre 2008

Salut,
Tu n'es pas constant dans ton utilisation des quotes ou doubles quotes.
De plus je ne vois pas trop l'utilité d'avoir une classe externe pour ça sachant que de toute façon tu n'utilise que mysql et que ta classe ne sert pas à grand chose mis à part surcharger.

Tu devrais prendre l'habitude d'utiliser les opérateurs de comparaisons de type à savoir ===, !== , etc. C'est pas obligatoire, c'est surtout qu'en programmation généralement on compare des pommes avec des pommes ;) même si php est pas trop strict c'est pas une raison...

Bon personellement je ne vois pas l'interet de ton code sachant qu'il y a déja des dizaines de codes comme celui ci sur phpcs, et que certains sont moin "brouillon".. Enfin, bonne continuation tout de même :)

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.