26
Jérôme CUTRONA Jérôme CUTRONA [email protected] [email protected] 16:54:06 16:54:06 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:43:39 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:43:39 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:5003:24:50 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:43:39 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

2203:24:5003:24:50 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 chaque page PHPDéconnexion en fin de chaque page PHP

Développement objet d'un site avec une BD :Développement objet d'un site avec une BD : Connexions à divers endroits dans les méthodesConnexions à divers endroits dans les méthodes Requête(s) à divers endroits dans les méthodesRequête(s) à divers endroits dans les méthodes Déconnexion en fin de page PHPDéconnexion en fin de page PHP

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:43:39 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

3303:24:5003:24:50 Programmation Web 2012-2013Programmation Web 2012-2013

Solution : SingletonSolution : Singleton

Singleton : objet à instance uniqueSingleton : objet à instance unique

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

SingletonSingleton 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:43:39 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

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

Solution : SingletonSolution : Singleton

Adaptation à la connexion BD PDO : Adaptation à la connexion BD PDO : myPDOmyPDO 1 attribut statique1 attribut statique

mypdomypdo 1 attribut statique1 attribut statique

Ressource BD = objet Ressource BD = objet PDOPDO 1 point d'accès1 point d'accès

Méthode statique Méthode statique get()get() 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

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

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

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

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

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 myPDO::get()myPDO::get()

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

BilanBilan : : connexion lors de la première requêteconnexion lors de la première requête déconnexion à la fin du scriptdéconnexion à la fin du script fonctionnement propre, transparent pour l'utilisateurfonctionnement propre, transparent pour l'utilisateur

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

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

Une implémentationUne implémentation

<?php<?php/// Classe permettant de faire une connexion unique /// Classe permettant de faire une connexion unique

et automatique à la BDet automatique à la BDfinal class myPDOfinal class myPDO{{        /// Singleton/// Singleton        private static private static $$mypdo mypdo = = null ;null ;        /// Message de debogage/// Message de debogage        private static private static $$debug debug = = true ;true ;        /// Data Source Name/// Data Source Name        private static private static $$dsn   dsn   = = null ;null ;        /// Utilisateur/// Utilisateur        private static private static $$user  user  = = null ;null ;        /// Mot de passe/// Mot de passe        private static private static $$pass  pass  = = null ;null ;        /// Connexion à la base/// Connexion à la base        private        private        $$pdo   pdo   = = null ;null ;

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

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

Une implémentationUne implémentation

/// Constructeur privé/// Constructeur privéprivate private function function __construct__construct() {() {        selfself::msg::msg("("Demande construction PDO..."Demande construction PDO...") ;) ;        if if (       (       is_nullis_null((selfself::$::$dsndsn))                        || || is_nullis_null((selfself::$::$useruser))                        || || is_nullis_null((selfself::$::$passpass))))                throw throw new new ExceptionException("("Construction impossible : Construction impossible :

les paramètres de connexion sont absents"les paramètres de connexion sont absents") ;) ;        // Etablir la connexion// Etablir la connexion        $$thisthis->pdo ->pdo = = new new PDOPDO((selfself::$::$dsn, dsn, selfself::$::$user, user,

selfself::$::$passpass) ;) ;        // Mise en place du mode "Exception" pour les // Mise en place du mode "Exception" pour les

erreurs PDOerreurs PDO        $$thisthis->pdo->setAttribute->pdo->setAttribute((PDOPDO::ATTR_ERRMODE,::ATTR_ERRMODE,

PDOPDO::ERRMODE_EXCEPTION::ERRMODE_EXCEPTION) ;) ;          selfself::msg::msg("("Construction PDO terminée"Construction PDO terminée") ;) ;}}

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

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

Une implémentationUne implémentation

/// Destructeur/// Destructeurpublic public function function __destruct__destruct() {() {        selfself::msg::msg("("Demande de destruction PDO..."Demande de destruction PDO...") ;) ;        // S'il y a une connexion établie...// S'il y a une connexion établie...        if if ((!!is_nullis_null(($$thisthis->pdo->pdo))))        {{                // ... il faut se deconnecter// ... il faut se deconnecter                selfself::msg::msg("("Demande de déconnexion..."Demande de déconnexion...") ;) ;                $$thisthis->pdo   ->pdo   = = null ;null ;                selfself::$::$mypdo mypdo = = null ;null ;                selfself::msg::msg("("Deconnexion effectuée"Deconnexion effectuée") ;) ;        }}        selfself::msg::msg("("Destruction PDO terminée"Destruction PDO terminée") ;) ;}}

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

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

Une implémentationUne implémentation

/// Récupérer le singleton/// Récupérer le singletonpublic static public static function donneInstancefunction donneInstance() {() {        selfself::msg::msg("("Recherche de l'instance..."Recherche de l'instance...") ;) ;        // Une instance est-elle disponible ?// Une instance est-elle disponible ?        if if ((!isset!isset((selfself::$::$mypdomypdo))))                selfself::$::$mypdo mypdo = = new myPDOnew myPDO() ;() ;        selfself::msg::msg("("Instance trouvée"Instance trouvée") ;) ;        return return selfself::$::$mypdomypdo->pdo->pdo ; ;}}

/// Fixer les paramètres de connexion/// Fixer les paramètres de connexionpublic static public static function parametresfunction parametres(($$_dsn,_dsn, $$_user, _user, $$_pass_pass) {) {        selfself::$::$dsn  dsn  = $= $_dsn ;_dsn ;        selfself::$::$user user = $= $_user ;_user ;        selfself::$::$pass pass = $= $_pass ;_pass ;}}

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

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

Une implémentationUne implémentation

/// Interdit le clonage du singleton/// Interdit le clonage du singletonpublic public function function __clone__clone() {() {        throw throw new new ExceptionException("("Clonage de Clonage de

""..__CLASS____CLASS__."." interdit !" interdit !") ;) ;}}

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

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

UtilisationUtilisation

require_once "require_once "connexion.pdo.template.class.php" ;connexion.pdo.template.class.php" ;

// Paramétrage du singleton// Paramétrage du singleton

myPDOmyPDO::parametres::parametres(('oci:dbname=bd11','oci:dbname=bd11',

'scott', 'tiger''scott', 'tiger') ;) ;

// Connexion automatique// Connexion automatique

$$pdostatpdostat == myPDO myPDO::::donneInstancedonneInstance()()->->queryquery((

""SELECT * FROM ImagesSELECT * FROM Images"")) ; ;

whilewhile (((($$ligneligne == $$pdostatpdostat->->fetchfetch())())

!==!== falsefalse))

{{

echoecho $$ligneligne[[''idid'']]..""<br><br>\n\n" ;" ;

}}

// Déconnexion automatique en fin de script// Déconnexion automatique en fin de script

Simple, non ?Simple, non ?

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

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

Raffinement possible : DébogageRaffinement possible : Débogage

Possibilité d'afficher des Possibilité d'afficher des messages informatifsmessages 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 : comment afficher des comment afficher des informations qui ne perturbent informations qui ne perturbent

pas l'affichagepas l'affichage de la page de la page commentairescommentaires HTML HTML <!-- … --><!-- … --> doit doit pouvoir être désactivépouvoir être désactivé contenus non HTML contenus non HTML

Implémentation :Implémentation : attributattribut booléen booléen statiquestatique et et méthodesméthodes statiquesstatiques

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

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

Raffinement possible : DébogageRaffinement possible : Débogage

Problème majeurProblème majeur, les méthodes de requête, , les méthodes de requête, préparation, etc sont des méthodes de l'objet préparation, etc sont des méthodes de l'objet PDOPDO et non de et non de myPDOmyPDO

Solution basiqueSolution basique la méthode la méthode getget retourne l'objet retourne l'objet myPDOmyPDO et non et non PDOPDO l'objet l'objet myPDOmyPDO doit implémenter toutes les méthodes doit implémenter toutes les méthodes

de de PDOPDO qui consistent à lancer celles de qui consistent à lancer celles de PDOPDO

Solution "avancée"Solution "avancée" la méthode la méthode get()get() retourne l'objet retourne l'objet myPDOmyPDO et non et non PDOPDO myPDOmyPDO doit implémenter doit implémenter __call__call

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

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

Une implémentation v2Une implémentation v2

/// Récupérer le singleton/// Récupérer le singletonpublic static public static function donneInstancefunction donneInstance() {() {        selfself::msg::msg("("Recherche de l'instance..."Recherche de l'instance...") ;) ;        // Une instance est-elle disponible ?// Une instance est-elle disponible ?        if if ((!isset!isset((selfself::$::$mypdomypdo))))                selfself::$::$mypdo mypdo = = new myPDOnew myPDO() ;() ;        selfself::msg::msg("("Instance trouvée"Instance trouvée") ;) ;        // return self::$mypdo->pdo ;// return self::$mypdo->pdo ;        return return selfself::$::$mypdo ;mypdo ;}}

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

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

Une implémentation v2Une implémentation v2

/// Surcharge de toutes les méthodes indisponibles de myPDO pour /// Surcharge de toutes les méthodes indisponibles de myPDO pour pouvoir appeler celles de PDOpouvoir appeler celles de PDO

public public function function __call__call(($$methodNamemethodName/** Nom de la méthode *//** Nom de la méthode */,,                              $$methodArguments methodArguments /** Tableau des paramètres *//** Tableau des paramètres */) {) {        // La méthode appelée fait-elle partie de la classe PDO// La méthode appelée fait-elle partie de la classe PDO

        if if ((!!method_existsmethod_exists(($$thisthis->pdo, ->pdo, $$methodNamemethodName))))                throw throw new new ExceptionException("("PDO::PDO::

$$methodNamemethodName n'existe pas" n'existe pas") ;) ;        // Message de debogage// Message de debogage        selfself::msg::msg("("PDO::PDO::

$$methodNamemethodName (" ("..implodeimplode(($$methodArguments, "methodArguments, ", , "")).".")")") ;) ;

        // Appel de la méthode avec l'objet PDO// Appel de la méthode avec l'objet PDO        $$result result = = call_user_func_arraycall_user_func_array((

arrayarray(($$thisthis->pdo, ->pdo, $$methodNamemethodName),),$$methodArgumentsmethodArguments) ;) ;

        return $return $result ;result ;}}

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

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

Une implémentation v2Une implémentation v2

/// Affichage de messages de contrôle/// Affichage de messages de contrôlepublic static public static function msgfunction msg(($$m m /** Le message *//** Le message */) {) {        if if ((selfself::$::$debugdebug))                TraceurTraceur::trace::trace(($$mm) ;) ;}}/// Mise en marche du debogage/// Mise en marche du debogagepublic static public static function debug_onfunction debug_on() {() {        selfself::$::$debug debug = = true ;true ;}}/// Arrêt du debogage/// Arrêt du debogagepublic static public static function debug_offfunction debug_off() {() {        selfself::$::$debug debug = = false ;false ;}}

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

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

Une implémentation v2 - DébogageUne implémentation v2 - 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:43:39 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

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

Une implémentation v2 - DébogageUne implémentation v2 - 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:43:39 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

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

Une implémentation v2 - DébogageUne implémentation v2 - 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:43:39 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

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

Une implémentation v2 - DébogageUne implémentation v2 - 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 21: Jérôme CUTRONA jerome.cutrona@univ-reims.fr 11:43:39 Programmation Web 2012-2013 1 Bases de données Objet singleton pour la connexion

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

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

Utilisation de la classe Traceur dans la classe Utilisation de la classe Traceur dans la classe myPDO : affichage des traces à la destructionmyPDO : affichage des traces à la destruction

/// Destructeur de myPDO/// Destructeur de myPDOpublic public function function __destruct__destruct() {() {        selfself::msg::msg("("Demande de destruction PDO..."Demande de destruction PDO...") ;) ;        // S'il y a une connexion établie...// S'il y a une connexion établie...        if if ((!!is_nullis_null(($$thisthis->pdo->pdo))))        {{                // ... il faut se deconnecter// ... il faut se deconnecter                selfself::msg::msg("("Demande de déconnexion..."Demande de déconnexion...") ;) ;                $$thisthis->pdo   ->pdo   = = null ;null ;                selfself::$::$mypdo mypdo = = null ;null ;                selfself::msg::msg("("Deconnexion effectuée"Deconnexion effectuée") ;) ;        }}        selfself::msg::msg("("Destruction PDO terminée"Destruction PDO terminée") ;) ;        echo Traceurecho Traceur::affiche::affiche() ;() ;}}

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

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

Raffinement possible : Débogage (suite)Raffinement possible : Débogage (suite)

La solution est La solution est partiellepartielle : : Les messages d'information concernent Les messages d'information concernent uniquement uniquement

les méthodes de les méthodes de PDOPDO Une Une requête préparéerequête préparée retourne un objet retourne un objet PDOStatementPDOStatement qui effectuera les méthodes qui effectuera les méthodes bindValuebindValue, , executeexecute, , fetchfetch, …, …

Comment tracer TOUTES les actions effectuées sur Comment tracer TOUTES les actions effectuées sur la base de données ?la base de données ?

Implémenter un objet Implémenter un objet myPDOStatementmyPDOStatement

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

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

Une implémentation V3Une implémentation V3

/// Encapsulation de PDOStatement/// Encapsulation de PDOStatementfinal class myPDOStatement final class myPDOStatement {{        /// L'objet PDOStatement/// L'objet PDOStatement        private private $$pdoStatement ;pdoStatement ;

        /// Constructeur/// Constructeur        public public function function __construct__construct(($$_pdoStatement_pdoStatement

/** L'objet PDOStatement /** L'objet PDOStatement */*/) {) {

                myPDOmyPDO::msg::msg("("Construction PDOStatement"Construction PDOStatement") ;) ;                $$thisthis->pdoStatement ->pdoStatement = $= $_pdoStatement ;_pdoStatement ;        }}

        /// Destructeur/// Destructeur        public public function function __destruct__destruct() {() {                myPDOmyPDO::msg::msg("("Destruction PDOStatement"Destruction PDOStatement") ;) ;                $$thisthis->pdoStatement ->pdoStatement = = null ;null ;        }}

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

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

Une implémentation V3Une implémentation V3

/// Surcharge de toutes les méthodes indisponibles de /// Surcharge de toutes les méthodes indisponibles de myPDOStatement pour pouvoir appeler celles de PDOStatementmyPDOStatement pour pouvoir appeler celles de PDOStatement

public public function function __call__call(($$methodNamemethodName/** Nom de la méthode *//** Nom de la méthode */,,                              $$methodArguments methodArguments /** Tableau des paramètres *//** Tableau des paramètres */) {) {        // La méthode appelée fait-elle partie de la classe PDOStatement// La méthode appelée fait-elle partie de la classe PDOStatement

        if if ((!!method_existsmethod_exists(($$thisthis->pdoStatement, ->pdoStatement, $$methodNamemethodName))))

                throw throw new new ExceptionException("("PDOStatement::PDOStatement::$$methodNamemethodName n'existe pas" n'existe pas") ;) ;

        // Message de debogage// Message de debogage

        myPDOmyPDO::msg::msg("("PDOStatement::"PDOStatement::".$.$methodNamemethodName..

"" (" ("..var_exportvar_export(($$methodArguments, methodArguments, truetrue)).".")")") ;) ;

        // Appel de la méthode avec l'objet PDOStatement// Appel de la méthode avec l'objet PDOStatement

        return return call_user_func_arraycall_user_func_array((

arrayarray(($$thisthis->pdoStatement, ->pdoStatement, $$methodNamemethodName),),

$$methodArgumentsmethodArguments) ;) ;

}}

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

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

Une implémentation V3.1Une implémentation V3.1

Utilisation de Utilisation de myPDOStatementmyPDOStatement au lieu de au lieu de PDOStatementPDOStatement ? ?

public public function function __call__call(($$methodNamemethodName/** Nom de la méthode *//** Nom de la méthode */,,                              $$methodArguments methodArguments /** Tableau des paramètres *//** Tableau des paramètres */) {) {        // La méthode appelée fait-elle partie de la classe PDO// La méthode appelée fait-elle partie de la classe PDO

        if if ((!!method_existsmethod_exists(($$thisthis->pdo, ->pdo, $$methodNamemethodName))))                throw throw new new ExceptionException("("PDO::PDO::$$methodNamemethodName n'existe  n'existe

pas"pas") ;) ;        // Message de debogage// Message de debogage        selfself::msg::msg("("PDO::PDO::

$$methodNamemethodName (" ("..implodeimplode(($$methodArguments, "methodArguments, ", ", ")).".")")") ;) ;        // Appel de la méthode avec l'objet PDO// Appel de la méthode avec l'objet PDO        $$result result = = call_user_func_arraycall_user_func_array((

arrayarray(($$thisthis->pdo, ->pdo, $$methodNamemethodName),),$$methodArgumentsmethodArguments) ;) ;

        return $return $result ;result ;}}

// Selon le nom de la méthode// Selon le nom de la méthodeswitchswitch (($$methodNamemethodName)) {{ // Cas 'prepare' ou 'query' => fetchNamed// Cas 'prepare' ou 'query' => fetchNamed casecase " "prepareprepare" " :: casecase " "queryquery" " :: $$resultresult->->setFetchModesetFetchMode((PDOPDO::::FETCH_NAMEDFETCH_NAMED)) ;; // Retourne un objet myPDOStatement// Retourne un objet myPDOStatement returnreturn newnew myPDOStatement myPDOStatement(($$resultresult)) ;; // Dans tous les autres cas// Dans tous les autres cas defaultdefault :: // Retourne le résultat// Retourne le résultat returnreturn $$resultresult ;;}}

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

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

Aide au débogage, suite (et fin ?)Aide au débogage, suite (et fin ?)

error_reportingerror_reporting((E_ALLE_ALL)) ;;

/** Mise en place d'une capture des /** Mise en place d'une capture des exceptions non attrapées */exceptions non attrapées */

functionfunction exceptionHandler exceptionHandler(($$exceptionexception

/** L'Exception non attrapée *//** L'Exception non attrapée */)) {{

echoecho " "<pre><pre>\n\n" " ;;

echoecho $$exceptionexception->->getMessagegetMessage()()..""\n\n" " ;;

echoecho " "Trace d'execution :Trace d'execution :\n\n" " ;;

echoecho $$exceptionexception->->getTraceAsStringgetTraceAsString()() ;;

echoecho " "</pre></pre>\n\n" " ;;

}}

set_exception_handlerset_exception_handler((''exceptionHandlerexceptionHandler'')) ;;