20
Jérôme CUTRONA Jérôme CUTRONA [email protected] [email protected] 12:19:51 12:19:51 Programmation Web 2012-2013 Programmation Web 2012-2013 1 Bases de données Bases de données Objet singleton pour la Objet singleton pour la connexion connexion

Jérôme CUTRONA [email protected] 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

Embed Size (px)

Citation preview

Page 1: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

Jérôme CUTRONAJérôme CUTRONA

[email protected]@univ-reims.fr

03:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013 11

Bases de donnéesBases de donnéesObjet singleton pour la connexionObjet singleton pour la connexion

Page 2: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

2203:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Problème poséProblème posé

Développement d'un site nécessitant une BD :Développement d'un site nécessitant une BD : Connexion en début de chaque page PHPConnexion en début de chaque page PHP Requête(s)Requête(s) Déconnexion en fin de programme PHPDéconnexion en fin de programme PHP

Développement objet d'un site avec une BD :Développement objet d'un site avec une BD : Connexion dès que la BD est utiliséeConnexion dès que la BD est utilisée Requête(s) à divers endroits dans les diverses Requête(s) à divers endroits dans les diverses

méthodes des diverses classesméthodes des diverses classes Déconnexion quand la BD n’est plus utileDéconnexion quand la BD n’est plus utile

Quand doit-on se connecter, se déconnecter ?Quand doit-on se connecter, se déconnecter ?

Page 3: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

3303:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Solution : patron de conception SingletonSolution : patron de conception Singleton

Singleton : objet à instance uniqueSingleton : objet à instance uniqueInstance uniqueInstance unique pour gérer une pour gérer une connexion BD uniqueconnexion BD unique

Réalisation :Réalisation : 1 attribut statique1 attribut statique

InstanceInstance 1 point d'accès1 point d'accès

méthode statiqueméthode statique limiter l'accès au constructeurlimiter l'accès au constructeur

privé / protégéprivé / protégé interdire le clonageinterdire le clonage

Page 4: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

Singleton : Illustration du fonctionnementSingleton : Illustration du fonctionnement

4403:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

<?php<?phpclassclass Singleton  Singleton {{    privateprivate  staticstatic  $$_instance_instance  ==  nullnull ; ;

public public      $$attrattr    ==  nullnull ;  ;

    publicpublic  staticstatic  functionfunction getInstance getInstance()()  {{

        ifif  ((!!selfself::$::$_instance_instance  instanceofinstanceof  selfself))  {{

            selfself::$::$_instance_instance  ==  newnew  selfself()() ; ;

        }}

        returnreturn  selfself::$::$_instance_instance ; ;

    }}

}}

$$i1i1  == Singleton Singleton::::getInstancegetInstance()() ; ;

$$i2i2  == Singleton Singleton::::getInstancegetInstance()() ; ;

$$i3i3  == Singleton Singleton::::getInstancegetInstance()() ; ;

$$i1i1->->attr attr ==  ""oursours"" ; ;

$$i3i3->->attr attr ==  4242 ; ;

echoecho  $$i2i2->->attr ;attr ;

ClasseClasse Singleton Singleton

getInstancegetInstance()()

$$_instance_instance

InstanceInstance Singleton Singleton

$$attrattr

$$i1i1

$$i2i2

$$i3i3

nullnull

nullnull

""oursours""4242

Page 5: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

5503:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Solution : patron de conception SingletonSolution : patron de conception Singleton

Adaptation à la connexion BD : Adaptation à la connexion BD : ConnexionConnexion 1 attribut statique1 attribut statique

instanceinstance 1 attribut de l’instance1 attribut de l’instance

Ressource BDRessource BD 1 point d'accès1 point d'accès

Méthode statique Méthode statique requeterequete constructeur privéconstructeur privé

établit la connexion à la BDétablit la connexion à la BD destructeurdestructeur

termine la connexion à la BDtermine la connexion à la BD mise hors service de la méthode mise hors service de la méthode __clone__clone

private ET throw new Exception("…") ;private ET throw new Exception("…") ;

Page 6: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

6603:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Durée de vie de l'objet Durée de vie de l'objet ConnexionConnexion

Nature de l'objetNature de l'objet membre statique d'une classe ≈ variable globalemembre statique d'une classe ≈ variable globale

ConstructionConstruction créé au premier appel de créé au premier appel de Connexion::requete()Connexion::requete()

DestructionDestruction variable globale : durée de vie = le programmevariable globale : durée de vie = le programme détruit automatiquement en fin de scriptdétruit automatiquement en fin de script

BilanBilan : : connexion automatique lors de la première requêteconnexion automatique lors de la première requête déconnexion automatique à la fin du scriptdéconnexion automatique à la fin du script facile, propre et transparent pour le développeurfacile, propre et transparent pour le développeur

Page 7: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

7703:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Raffinement possible : DébogageRaffinement possible : Débogage

possibilité de collecter des messages informatifs possibilité de collecter des messages informatifs pour se rendre compte de ce qu'il se passe et pour se rendre compte de ce qu'il se passe et dépister les erreurs :dépister les erreurs : connexion…connexion… requête…requête…

Cadre Web :Cadre Web : ne pas perturber la page : commentaires HTMLne pas perturber la page : commentaires HTML doit pouvoir être désactivé doit pouvoir être désactivé contenu des images contenu des images

Implémentation :Implémentation : attribut booléen statique et méthodes statiquesattribut booléen statique et méthodes statiques utilisation d’un singleton de collecte d’informationsutilisation d’un singleton de collecte d’informations

Page 8: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

8803:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentationUne implémentation

/// Singleton permettant d'effectuer une connexion unique à la BD/// Singleton permettant d'effectuer une connexion unique à la BD

classclass Connexion Connexion

{{    // Paramètres de connexion à la base de données// Paramètres de connexion à la base de données

    privateprivate  staticstatic  $$_host_host      ==  nullnull ;  ; /// Hôte MySQL/// Hôte MySQL

    privateprivate  staticstatic  $$_user_user      ==  nullnull ;  ; /// Utilisateur MySQL/// Utilisateur MySQL

    privateprivate  staticstatic  $$_passwd_passwd  ==  nullnull ;  ; /// Mot de passe MySQL/// Mot de passe MySQL

    privateprivate  staticstatic  $$_base_base      ==  nullnull ;  ; /// Base de données de travail/// Base de données de travail

      // Gestion de l'instance unique// Gestion de l'instance unique

    privateprivate  staticstatic  $$_instance_instance  ==  nullnull ;  ; /// Objet Connexion/// Objet Connexion

    // Traces d'exécution// Traces d'exécution

    privateprivate  staticstatic  $$_traces_traces          ==  truetrue ;  ; /// Débogage actif ou non/// Débogage actif ou non

      // Attribut de l'objet : ressource de la connexion à la base de données// Attribut de l'objet : ressource de la connexion à la base de données

    privateprivate                $$_ressourceBD_ressourceBD  ==  nullnull ;  ; /// Connexion à la base/// Connexion à la base

Page 9: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

9903:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentationUne implémentation

/// Constructeur privé/// Constructeur privé

privateprivate  functionfunction  __construct__construct()()  {{

        selfself::::msgmsg((""Construction de l'objet Connexion...Construction de l'objet Connexion..."")) ; ;

        // Vérifier la présence des paramètres de connexion// Vérifier la présence des paramètres de connexion

        ifif  ((              is_nullis_null((selfself::$::$_host_host))

                        ||||  is_nullis_null((selfself::$::$_user_user))

                        ||||  is_nullis_null((selfself::$::$_passwd_passwd))

                        ||||  is_nullis_null((selfself::$::$_base_base))))

                throwthrow  newnew  ExceptionException((""Connexion impossible : les Connexion impossible : les

paramètres de connexion sont absentsparamètres de connexion sont absents"")) ; ;

        // Etablir la connexion// Etablir la connexion

        ifif  ((!!  (($$tmptmp  == @ @mysql_connectmysql_connect((selfself::$::$_host_host,,

selfself::$::$_user_user, , selfself::$::$_passwd_passwd))))))

                throwthrow  newnew  ExceptionException((""Connexion impossible à la base de Connexion impossible à la base de

donnéesdonnées"")) ; ;

        $$thisthis->->_ressourceBD _ressourceBD ==  $$tmptmp ; ;

Page 10: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

101003:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentationUne implémentation

        // Sélectionner la base de donnees// Sélectionner la base de donnees

        ifif  ((!! @ @mysql_select_dbmysql_select_db((selfself::$::$_base_base,,

$$thisthis->->_ressourceBD_ressourceBD))))

                throwthrow  newnew  ExceptionException((""Sélection de la base impossible : Sélection de la base impossible : ""

..mysql_errormysql_error(($$thisthis->->_ressourceBD_ressourceBD)))) ; ;

        // Mise en place de la table de caractères// Mise en place de la table de caractères

        mysql_querymysql_query((""SET CHARACTER SET 'utf8'SET CHARACTER SET 'utf8'",",

$$thisthis->->_ressourceBD_ressourceBD)) ; ;

        selfself::::msgmsg((""Construction terminéeConstruction terminée"")) ; ;

}}

Page 11: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

111103:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentationUne implémentation

/// Destructeur/// Destructeur

publicpublic  functionfunction  __destruct__destruct()()  {{

        selfself::::msgmsg((""Demande de destruction de l'objet Connexion...Demande de destruction de l'objet Connexion..."")) ; ;

        // S'il y a une connexion établie...// S'il y a une connexion établie...

        ifif  ((!!is_nullis_null(($$thisthis->->_ressourceBD_ressourceBD))))  {{

                // ... il faut se déconnecter// ... il faut se déconnecter

                selfself::::msgmsg((""Demande de déconnexion...Demande de déconnexion..."")) ; ;

                mysql_closemysql_close(($$thisthis->->_ressourceBD_ressourceBD)) ; ;

                $$thisthis->->_ressourceBD _ressourceBD ==  nullnull ; ;

                selfself::$::$_instance_instance        ==  nullnull ; ;

                selfself::::msgmsg((""Déconnexion effectuéeDéconnexion effectuée"")) ; ;

        }}

        selfself::::msgmsg((""Destruction terminéeDestruction terminée"")) ; ;

        // Affichage des traces si le Débogage est actif// Affichage des traces si le Débogage est actif

        ifif  ((selfself::$::$_traces_traces))  {{

                echoecho Traceur Traceur::::afficheaffiche()() ; ;

        }}

}}

Page 12: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

121203:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentationUne implémentation

/// Accesseur à l'instance qui sera créée si nécessaire/// Accesseur à l'instance qui sera créée si nécessaire

privateprivate  functionfunction donneInstance donneInstance()()  {{

        selfself::::msgmsg((""Recherche de l'instance...Recherche de l'instance..."")) ; ;

        // Existe-t-il une instance de Connexion ?// Existe-t-il une instance de Connexion ?

        ifif  ((is_nullis_null((selfself::$::$_instance_instance))))  {{

                // NON : il faut en créer une// NON : il faut en créer une

                selfself::$::$_instance_instance  ==  newnew Connexion Connexion()() ; ;

        }}

        selfself::::msgmsg((""Instance trouvéeInstance trouvée"")) ; ;

        returnreturn  selfself::$::$_instance_instance ; ;

}}

  

/// Accesseur à la connexion à la base de données/// Accesseur à la connexion à la base de données

privateprivate  staticstatic  functionfunction donneRessourceBD donneRessourceBD()()  {{

        selfself::::msgmsg((""Recherche de la ressource BD...Recherche de la ressource BD..."")) ; ;

        returnreturn  selfself::::donneInstancedonneInstance()()->->_ressourceBD ;_ressourceBD ;

}}

Page 13: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

131303:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentationUne implémentation

/// Fixer les paramètres de connexion/// Fixer les paramètres de connexion

publicpublic  staticstatic  functionfunction parametres parametres(($$hosthost, , $$useruser, , $$passwdpasswd,,

$$basebase, , $$tracestraces))  {{

        selfself::::debogagedebogage(($$tracestraces)) ; ;

        selfself::::msgmsg((

""Demande de positionnement des paramètres de connexion...Demande de positionnement des paramètres de connexion..."")) ; ;

        selfself::$::$_host_host      ==  $$hosthost ; ;

        selfself::$::$_user_user      ==  $$useruser ; ;

        selfself::$::$_passwd_passwd  ==  $$passwdpasswd ; ;

        selfself::$::$_base_base      ==  $$basebase ; ;

        selfself::::msgmsg((""Positionnement des paramètres de connexion terminéPositionnement des paramètres de connexion terminé"")) ; ;

}}

Page 14: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

141403:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentationUne implémentation

/// Effectuer une requête et retourner le résultat/// Effectuer une requête et retourner le résultat

publicpublic  staticstatic  functionfunction requete requete(($$reqreq))  {{

        selfself::::msgmsg((""Demande d'exécution de la requête:Demande d'exécution de la requête:\n\n$$reqreq"")) ; ;

        $$resres  == @ @mysql_querymysql_query(($$reqreq,,

selfself::::donneRessourceBDdonneRessourceBD())()) ; ;

        ifif  (($$resres  ======  falsefalse))  {{

                throwthrow  newnew  ExceptionException((""Erreur pour la requête 'Erreur pour la requête '{{$$reqreq}}' : ' : ""

..mysql_errormysql_error((selfself::::donneRessourceBDdonneRessourceBD()))())) ; ;

        }}

        selfself::::msgmsg((""Requête effectuéeRequête effectuée"")) ; ;

        returnreturn  $$resres ; ;

}}

Page 15: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

151503:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentationUne implémentation

/// Protéger une chaîne de caractères avant de l'intégrer dans une requête/// Protéger une chaîne de caractères avant de l'intégrer dans une requête

publicpublic  staticstatic  functionfunction protectionChaine protectionChaine(($$chainechaine))  {{

        selfself::::msgmsg((""Protection de la chaine 'Protection de la chaine '{{$$chainechaine}}''"")) ; ;

        returnreturn  mysql_real_escape_stringmysql_real_escape_string(($$chainechaine,,

selfself::::donneRessourceBDdonneRessourceBD())()) ; ;

}}

  

/// Retouner le nombre d'enregistrements affectes/// Retouner le nombre d'enregistrements affectes

publicpublic  staticstatic  functionfunction nombreLignesAffectees nombreLignesAffectees()()  {{

        returnreturn  mysql_affected_rowsmysql_affected_rows((selfself::::donneRessourceBDdonneRessourceBD())()) ; ;

}}

  

/// Interdire le clonage/// Interdire le clonage

privateprivate  functionfunction  __clone__clone()()  {{

        throwthrow  newnew  ExceptionException((""Clonage de Clonage de ""..__CLASS____CLASS__.."" interdit ! interdit !"")) ; ;

}}

Page 16: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

161603:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentationUne implémentation

/// Collecte de messages de contrôle/// Collecte de messages de contrôle

staticstatic  functionfunction msg msg(($$messagemessage))  {{

        ifif  ((selfself::$::$_traces_traces))

                TraceurTraceur::::tracetrace(($$messagemessage)) ; ;

}}

  

/// Mise en marche ou arrêt des messages de contrôle/// Mise en marche ou arrêt des messages de contrôle

staticstatic  functionfunction debogage debogage(($$etatetat))  {{

        selfself::$::$_traces_traces  ==  ((boolbool))  $$etatetat ; ;

}}

}}

Page 17: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

171703:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentation - DébogageUne implémentation - Débogage

/// Singleton permettant de collecter des messages informatifs/// Singleton permettant de collecter des messages informatifs

classclass Traceur  Traceur {{

// Gestion de l'instance unique// Gestion de l'instance unique

privateprivate  staticstatic  $$_instance_instance  ==  nullnull ;  ; /// Objet Traceur/// Objet Traceur

  

// Atttributs de l'objet// Atttributs de l'objet

privateprivate                $$_messages_messages  ==  arrayarray()() ;  ; /// Tableau des messages/// Tableau des messages

privateprivate                $$_temps_temps        ==  nullnull ;     ;    /// Instant de création/// Instant de création

  

/// Constructeur privé/// Constructeur privé

privateprivate  functionfunction  __construct__construct()()  {{

        $$thisthis->->_temps _temps ==  microtimemicrotime((truetrue)) ; ;

}}

  

/// Interdire le clonage/// Interdire le clonage

privateprivate  functionfunction  __clone__clone()()  {{

        throwthrow  newnew  ExceptionException((""Clonage de Clonage de ""..__CLASS____CLASS__.."" interdit ! interdit !"")) ; ;

}}

Page 18: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

181803:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentation - DébogageUne implémentation - Débogage

  

/// Accesseur à l'instance qui sera créée si nécessaire/// Accesseur à l'instance qui sera créée si nécessaire

privateprivate  staticstatic  functionfunction donneInstance donneInstance()()  {{

        ifif  ((is_nullis_null((selfself::$::$_instance_instance))))  {{

                selfself::$::$_instance_instance  ==  newnew  selfself()() ; ;

        }}

        returnreturn  selfself::$::$_instance_instance ; ;

}}

  

/// Méthode statique de collecte de messages/// Méthode statique de collecte de messages

publicpublic  staticstatic  functionfunction trace trace(($$msgmsg))  {{

        $$instanceinstance  ==  selfself::::donneInstancedonneInstance()() ; ;

        $$instanceinstance->->messagesmessages[][]  ==  $$instanceinstance->->dureeduree()()  .. " " secondes :  secondes : "  "  ..

$$msgmsg ; ;

}}

Page 19: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

191903:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Une implémentation - DébogageUne implémentation - Débogage

/// Calcul du temps écoulé depuis la création du traceur/// Calcul du temps écoulé depuis la création du traceur

privateprivate  functionfunction duree duree()()  {{

        returnreturn  number_formatnumber_format((microtimemicrotime((truetrue))  --  $$thisthis->->_temps, _temps, 44)) ; ;

}}  

/// Méthode statique d'affichage des messages collectés/// Méthode statique d'affichage des messages collectés

publicpublic  staticstatic  functionfunction affiche affiche(($$avantavant  == " "<!--<!--", ", $$apresapres  == " "-->-->""))  {{

        $$messagesmessages  ==    selfself::::donneInstancedonneInstance()()->->messages ;messages ;

        $$tracestraces  ==  nullnull ; ;

        ifif  ((countcount(($$messagesmessages))))  {{

                $$tracestraces  .=.=  ""{{$$avantavant}\n}\n" ;" ;

                foreachforeach  (($$messagesmessages  asas  $$mm))  {{

                        $$tracestraces  .=.= " "{{$$mm}\n}\n" ;" ;

                }}

                $$tracestraces  .=.= " "{{$$apresapres}\n}\n" ;" ;

        }}

  

        returnreturn  $$tracestraces ; ;

} }} }

Page 20: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:51:49 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

202003:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

UtilisationUtilisation

require_oncerequire_once " "connexion.mysql.template.class.phpconnexion.mysql.template.class.php" ;" ;ConnexionConnexion::::parametresparametres((''serveurserveur', '', 'utilisateurutilisateur',', ''motdepassemotdepasse', '', 'basededoneesbasededonees', ', truetrue)) ; ;  // Exemple d'utilisation :// Exemple d'utilisation :$$resres  == Connexion Connexion::::requeterequete((<<<<<<SQLSQL        SELECTSELECT un_champ un_champ        FROMFROM une_table une_table        ORBER ORBER BYBY  11SQLSQL        )) ; ;whilewhile  (($$ligneligne  ==  mysql_fetch_assocmysql_fetch_assoc(($$resres))))  {{        /* ... */ /* ... */ $$ligneligne[[''un_champun_champ''] ] /* ... */ /* ... */ ;;}}

Simple, non ?Simple, non ?