Bases de données Objet singleton pour la connexion

Présentations similaires


Présentation au sujet: "Bases de données Objet singleton pour la connexion"— Transcription de la présentation:

1 Bases de données Objet singleton pour la connexion
01:08:10 Programmation Web

2 Problème posé Développement d'un site nécessitant une BD :
Connexion en début de chaque page PHP Requête(s) Déconnexion en fin de programme PHP Développement objet d'un site avec une BD : Connexion dès que la BD est utilisée Requête(s) à divers endroits dans les diverses méthodes des diverses classes Déconnexion quand la BD n’est plus utile  Quand doit-on se connecter, se déconnecter ? 01:08:10 Programmation Web

3 Solution : patron de conception Singleton
Singleton : objet à instance unique Instance unique pour gérer une connexion BD unique Réalisation : 1 attribut statique Instance 1 point d'accès méthode statique limiter l'accès au constructeur privé / protégé interdire le clonage 01:08:10 Programmation Web

4 Singleton : Illustration du fonctionnement
<?php class Singleton {   private static $_instance = null ; public    $attr  = null ;   public static function getInstance() {     if (!self::$_instance instanceof self) {       self::$_instance = new self() ;     }     return self::$_instance ;   } } $i1 = Singleton::getInstance() ; $i2 = Singleton::getInstance() ; $i3 = Singleton::getInstance() ; $i1->attr = "ours" ; $i3->attr = 42 ; echo $i2->attr ; Classe Singleton getInstance() $_instance null $i1 Instance Singleton $attr $i2 $i3 "ours" 42 null 01:08:10 Programmation Web

5 Solution : patron de conception Singleton
Adaptation à la connexion BD : Connexion 1 attribut statique instance 1 attribut de l’instance Ressource BD 1 point d'accès Méthode statique requete constructeur privé établit la connexion à la BD destructeur termine la connexion à la BD mise hors service de la méthode __clone private ET throw new Exception("…") ; 01:08:10 Programmation Web

6 Durée de vie de l'objet Connexion
Nature de l'objet membre statique d'une classe ≈ variable globale Construction créé au premier appel de Connexion::requete() Destruction variable globale : durée de vie = le programme détruit automatiquement en fin de script Bilan : connexion automatique lors de la première requête déconnexion automatique à la fin du script facile, propre et transparent pour le développeur 01:08:10 Programmation Web

7 Raffinement possible : Débogage
possibilité de collecter des messages informatifs pour se rendre compte de ce qu'il se passe et dépister les erreurs : connexion… requête… Cadre Web : ne pas perturber la page : commentaires HTML doit pouvoir être désactivé  contenu des images Implémentation : attribut booléen statique et méthodes statiques utilisation d’un singleton de collecte d’informations 01:08:10 Programmation Web

8 Une implémentation class Connexion {
/// Singleton permettant d'effectuer une connexion unique à la BD class Connexion {   // Paramètres de connexion à la base de données   private static $_host   = null ; /// Hôte MySQL   private static $_user   = null ; /// Utilisateur MySQL   private static $_passwd = null ; /// Mot de passe MySQL   private static $_base   = null ; /// Base de données de travail   // Gestion de l'instance unique   private static $_instance = null ; /// Objet Connexion   // Traces d'exécution   private static $_traces     = true ; /// Débogage actif ou non   // Attribut de l'objet : ressource de la connexion à la base de données   private        $_ressourceBD = null ; /// Connexion à la base 01:08:10 Programmation Web

9 Une implémentation /// Constructeur privé
private function __construct() {     self::msg("Construction de l'objet Connexion...") ;     // Vérifier la présence des paramètres de connexion     if (       is_null(self::$_host)             || is_null(self::$_user)             || is_null(self::$_passwd)             || is_null(self::$_base))         throw new Exception("Connexion impossible : les paramètres de connexion sont absents") ;     // Etablir la connexion self::$_user, self::$_passwd)))         throw new Exception("Connexion impossible à la base de données") ;     $this->_ressourceBD = $tmp ; 01:08:10 Programmation Web

10 Une implémentation // Sélectionner la base de donnees
$this->_ressourceBD))         throw new Exception("Sélection de la base impossible : " .mysql_error($this->_ressourceBD)) ;     // Mise en place de la table de caractères     mysql_query("SET CHARACTER SET 'utf8'", $this->_ressourceBD) ;     self::msg("Construction terminée") ; } 01:08:10 Programmation Web

11 Une implémentation /// Destructeur public function __destruct() {
    self::msg("Demande de destruction de l'objet Connexion...") ;     // S'il y a une connexion établie...     if (!is_null($this->_ressourceBD)) {         // ... il faut se déconnecter         self::msg("Demande de déconnexion...") ;         mysql_close($this->_ressourceBD) ;         $this->_ressourceBD = null ;         self::$_instance    = null ;         self::msg("Déconnexion effectuée") ;     }     self::msg("Destruction terminée") ;     // Affichage des traces si le Débogage est actif     if (self::$_traces) {         echo Traceur::affiche() ; } 01:08:10 Programmation Web

12 Une implémentation /// Accesseur à l'instance qui sera créée si nécessaire private function donneInstance() {     self::msg("Recherche de l'instance...") ;     // Existe-t-il une instance de Connexion ?     if (is_null(self::$_instance)) {         // NON : il faut en créer une         self::$_instance = new Connexion() ;     }     self::msg("Instance trouvée") ;     return self::$_instance ; } /// Accesseur à la connexion à la base de données private static function donneRessourceBD() {     self::msg("Recherche de la ressource BD...") ;     return self::donneInstance()->_ressourceBD ; 01:08:10 Programmation Web

13 Une implémentation /// Fixer les paramètres de connexion
public static function parametres($host, $user, $passwd, $base, $traces) {     self::debogage($traces) ;     self::msg( "Demande de positionnement des paramètres de connexion...") ;     self::$_host   = $host ;     self::$_user   = $user ;     self::$_passwd = $passwd ;     self::$_base   = $base ;     self::msg("Positionnement des paramètres de connexion terminé") ; } 01:08:10 Programmation Web

14 Une implémentation /// Effectuer une requête et retourner le résultat
public static function requete($req) {     self::msg("Demande d'exécution de la requête:\n$req") ; self::donneRessourceBD()) ;     if ($res === false) {         throw new Exception("Erreur pour la requête '{$req}' : " .mysql_error(self::donneRessourceBD())) ;     }     self::msg("Requête effectuée") ;     return $res ; } 01:08:10 Programmation Web

15 Une implémentation public static function protectionChaine($chaine) {
/// Protéger une chaîne de caractères avant de l'intégrer dans une requête public static function protectionChaine($chaine) {     self::msg("Protection de la chaine '{$chaine}'") ;     return mysql_real_escape_string($chaine, self::donneRessourceBD()) ; } /// Retouner le nombre d'enregistrements affectes public static function nombreLignesAffectees() {     return mysql_affected_rows(self::donneRessourceBD()) ; /// Interdire le clonage private function __clone() {     throw new Exception("Clonage de ".__CLASS__." interdit !") ; 01:08:10 Programmation Web

16 Une implémentation /// Collecte de messages de contrôle
static function msg($message) {     if (self::$_traces)         Traceur::trace($message) ; } /// Mise en marche ou arrêt des messages de contrôle static function debogage($etat) {     self::$_traces = (bool) $etat ; 01:08:10 Programmation Web

17 Une implémentation - Débogage
/// Singleton permettant de collecter des messages informatifs class Traceur { // Gestion de l'instance unique private static $_instance = null ; /// Objet Traceur // Atttributs de l'objet private        $_messages = array() ; /// Tableau des messages private        $_temps    = null ;    /// Instant de création /// Constructeur privé private function __construct() {     $this->_temps = microtime(true) ; } /// Interdire le clonage private function __clone() {     throw new Exception("Clonage de ".__CLASS__." interdit !") ; 01:08:10 Programmation Web

18 Une implémentation - Débogage
/// Accesseur à l'instance qui sera créée si nécessaire private static function donneInstance() {     if (is_null(self::$_instance)) {         self::$_instance = new self() ;     }     return self::$_instance ; } /// Méthode statique de collecte de messages public static function trace($msg) {     $instance = self::donneInstance() ;     $instance->messages[] = $instance->duree() . " secondes : "  .$msg ; 01:08:10 Programmation Web

19 Une implémentation - Débogage
/// Calcul du temps écoulé depuis la création du traceur private function duree() {     return number_format(microtime(true) - $this->_temps, 4) ; } /// Méthode statique d'affichage des messages collectés public static function affiche($avant = "<!--", $apres = "-->") {     $messages =  self::donneInstance()->messages ;     $traces = null ;     if (count($messages)) {         $traces .= "{$avant}\n" ;         foreach ($messages as $m) {             $traces .= "{$m}\n" ;         }         $traces .= "{$apres}\n" ;     }     return $traces ; } } 01:08:10 Programmation Web

20 Simple, non ? Utilisation
require_once "connexion.mysql.template.class.php" ; Connexion::parametres('serveur', 'utilisateur', 'motdepasse', 'basededonees', true) ; // Exemple d'utilisation : $res = Connexion::requete(<<<SQL     SELECT un_champ     FROM une_table     ORBER BY 1 SQL     ) ; while ($ligne = mysql_fetch_assoc($res)) {     /* ... */ $ligne['un_champ'] /* ... */ ; } Simple, non ? 01:08:10 Programmation Web


Télécharger ppt "Bases de données Objet singleton pour la connexion"
Annonces Google