Bases de données Objet singleton pour la connexion

Slides:



Advertisements
Présentations similaires
PHP5 its a kind of magic. Chargement automatique function __autoload( $nom_classe ) { require_once('obj/'.$nom_classe.'.class.php'); } si on exécute le.
Advertisements

ASP.NET v2 + Ajax = Atlas Pierre Lagarde DevDays 2006 Equipé aujourdhui, prêt pour demain !
IChannelIPrivilegedIMultithreadedIServantICacheableIMimeResponse Type custom : les interfaces de programmations IChannel : canal standard, stateful 5 méthodes.
C++ 6ème cours Patrick Reuter maître de conférences
C++ 5ème cours Patrick Reuter maître de conférences
LA TECHNOLOGIE WAP WIRLESS APPLICATION PROTOCOL Arnaud MERGEY Davy RIBOUD David ZAMORA DESS RESEAUX 2000/2001.
Exposé de Système - Informatique et Réseau
TRANSFER Alger – Serveur Web Nicolas Larrousse Septembre Petit historique du Worl Wide Web Notion dHypertexte Extension à internet par Tim Berners.
PHP5 poo.
PHP5 its a kind of magic. Chargement automatique function __autoload( $nom_classe ) { require_once('obj/'.$nom_classe.'.class.php'); } si on exécute le.
Programmation Orientée Objet (POO)
TP 3-4 BD21.
Servlet JAVA.
10:59:29 Programmation Web Programmation Web : PHP Jérôme CUTRONA
Programmation Web : Protocole HTTP
11:02:471 Programmation Web : Flux RSS Jérôme CUTRONA Programmation Web
11:16:331 Programmation Web Programmation Web : Formulaires HTML Jérôme CUTRONA
11:20:16 Programmation Web PHP Création et manipulation d'images Jérôme CUTRONA
Jérôme CUTRONA PHP et bases de données Jérôme CUTRONA 01:07:51 Programmation Web
PhpMyAdmin 01:08:02 Programmation Web
Jérôme CUTRONA PHP objet Jérôme CUTRONA 01:08:01 Programmation Web
Jérôme CUTRONA PHP PDO Jérôme CUTRONA 01:08:01 Programmation Web
11:37:32 Programmation Web PHP5 objet "avancé" Jérôme CUTRONA
PHP Interface base de données
Bases de données Objet singleton pour la connexion
Windows XP Professionnel
Integration serveur Data Access Layer Web Service Service1.asmx BankAccess FinanceAccess CLIENTS Business Logic Layer Finance Portfolio SOURCE DE DONNEES.
Integration serveur Data Access Layer Web Service Service1.asmx BankAccess FinanceAccess CLIENTS Business Logic Layer Finance Portfolio SOURCE DE DONNEES.
[Titre de la recherche] [Qui sommes-nous?]. Pourquoi ce sujet ? [Motivations ayant menées au choix du sujet]
© Alliance suisse des samaritains ASS – Transparent 1 Lextranet de lASS Etat des travaux Poursuite de la planification Solutions pour les associations.
Connexion base de données
Chapitre IV Object, interfaces, classes imbriquées.
BlueJ_XI 1 Java, les objets : tout de suite ! Gestion des erreurs : les exceptions Notes de cours associées au chapitre 11 tutorial BlueJ
Faculté I&C, Claude Petitpierre, André Maurer 1 Java.
#JSS2013 Les journées SQL Server 2013 Un événement organisé par GUSS.
Introduction au paradigme objet Concepts importants surcharge (overload) redéfinition (override) Définition d’une classe Définition des attributs.
Historique de SystemC Regroupe 4 courants didées: SCENIC Project : Synopsys+UC Irvine Philips System-Level Data Types, VSIA SLD DWG IMEC, Hardware-Software.
Projet poker 1/56. Introduction Présentation de léquipe Cadre du projet Enjeux Choix du sujet 2.
SQL Injection Réalisée par: BEN NASR Houssem GMATI Idriss HADDAD Mohamed Aymen HAKIM Youssef.
ADOBE FLEX 4. © Logica All rights reservedNo. 2 Introduction Flex en action Autour de Flex Logica Le programme.
Structures de données IFT-2000
Projet Génie Logiciel & UML, Bases de Données & Interfaces
Faculté I&C, Claude Petitpierre, André Maurer 1 Concepts dhéritage Héritage dimplémentation hasA Héritage de spécialisation isA.
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 3 : Classes et Objects.
Types de données abstrait et mécanismes d'encapsulation
Cours 11 Threads. Chapitre X threads threadPOO-L3 H. Fauconnier3 Threads threads: plusieurs activités qui coexistent et partagent des données exemples:
COURS DE PROGRAMMATION ORIENTEE OBJET :
Leçon 1 : notion dobjet IUP Génie Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
Document élaboré à Centrale Paris par Pascal Morenton LES TECHNOLOGIES DU WEB 1. LES PHASES D UN DEPLOIEMENT DE RESEAUX 2. LE LANGAGE HTML 3. LE LANGAGE.
Patrons de conceptions de créations
Techniques Internet de Base Licence 2 (Info, Maths, PC/PA) Université Jean Monnet Ruggero G. PENSA
JavaScript Nécessaire Web.
Cours 61 6 La sécurité, Portée, Visibilité Programmer avec sécurité.
ESA Ecole Supérieure des Affaires Ernaelsten Gérard - Frédéric FiléePage 285 Cours de Programmation Web : PHP Chapitre 5 : Orienté objet en PHP.
0 Objectifs de la session n°1  Revenir sur toutes les bases théoriques nécessaires pour devenir un développeur Web,  Découvrir l’ensemble des langages.
Jérôme CUTRONA PHP PDO Jérôme CUTRONA 07:21:24 Programmation Web
PHP 7° PARTIE : PROGRAMMATION OBJET
PHP objet Jérôme CUTRONA 10:13:27 Programmation Web
420-B63 Programmation Web Avancée Auteur : Frédéric Thériault 1.
PHP5 objet "avancé" Jérôme CUTRONA 09:56:48 Programmation Web
Programmation Web : PHP
Protocole HTTP, cookies, sessions, authentification
M2 – MIAGE/SID Servlet et session M2 – MIAGE/SID
Bases de données Singleton pour la connexion
Exception Handling "Unfortunately, it's almost accepted practice to ignore error conditions, as if we're in a state of denial about errors." Bruce Eckel.
APP-TSWD Apprentissage Par Problèmes Techniques des Sites Web Dynamiques Licence Professionnelle FNEPI Valérie Bellynck, Benjamin Brichet-Billet, Mazen.
Introduction à la Programmation Orientée Objet H.GATI.
PAGE 1 PAGE 2.
Bases de données Singleton pour la connexion
Transcription de la présentation:

Bases de données Objet singleton pour la connexion 01:08:06 Programmation Web 2012-2013

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 chaque page PHP Développement objet d'un site avec une BD : Connexions à divers endroits dans les méthodes Requête(s) à divers endroits dans les méthodes Déconnexion en fin de page PHP  Quand doit-on se connecter, se déconnecter ? 01:08:06 Programmation Web 2012-2013

Singleton : objet à instance unique Réalisation : Solution : Singleton Singleton : objet à instance unique Réalisation : 1 attribut statique Singleton 1 point d'accès méthode statique limiter l'accès au constructeur privé / protégé interdire le clonage 01:08:06 Programmation Web 2012-2013

Solution : Singleton Adaptation à la connexion BD PDO : myPDO 1 attribut statique mypdo Ressource BD = objet PDO 1 point d'accès Méthode statique get() constructeur privé établit la connexion à la BD destructeur termine la connexion à la BD mise hors service de la méthode __clone throw new Exception("…") ; 01:08:06 Programmation Web 2012-2013

Durée de vie de l'objet myPDO Nature de l'objet membre statique d'une classe : variable globale Construction créé au premier appel de myPDO::get() Destruction variable globale : durée de vie = le script détruit en fin de script Bilan : connexion lors de la première requête déconnexion à la fin du script fonctionnement propre, transparent pour l'utilisateur 01:08:06 Programmation Web 2012-2013

Une implémentation <?php /// Classe permettant de faire une connexion unique et automatique à la BD final class myPDO {     /// Singleton     private static $mypdo = null ;     /// Message de debogage     private static $debug = true ;     /// Data Source Name     private static $dsn   = null ;     /// Utilisateur     private static $user  = null ;     /// Mot de passe     private static $pass  = null ;     /// Connexion à la base     private        $pdo   = null ; 01:08:06 Programmation Web 2012-2013

Une implémentation /// Constructeur privé private function __construct() {     self::msg("Demande construction PDO...") ;     if (       is_null(self::$dsn)             || is_null(self::$user)             || is_null(self::$pass))         throw new Exception("Construction impossible : les paramètres de connexion sont absents") ;     // Etablir la connexion     $this->pdo = new PDO(self::$dsn, self::$user, self::$pass) ;     // Mise en place du mode "Exception" pour les erreurs PDO     $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ;      self::msg("Construction PDO terminée") ; } 01:08:06 Programmation Web 2012-2013

Une implémentation /// Destructeur public function __destruct() {     self::msg("Demande de destruction PDO...") ;     // S'il y a une connexion établie...     if (!is_null($this->pdo))     {         // ... il faut se deconnecter         self::msg("Demande de déconnexion...") ;         $this->pdo   = null ;         self::$mypdo = null ;         self::msg("Deconnexion effectuée") ;     }     self::msg("Destruction PDO terminée") ; } 01:08:06 Programmation Web 2012-2013

Une implémentation /// Récupérer le singleton public static function donneInstance() {     self::msg("Recherche de l'instance...") ;     // Une instance est-elle disponible ?     if (!isset(self::$mypdo))         self::$mypdo = new myPDO() ;     self::msg("Instance trouvée") ;     return self::$mypdo->pdo ; } /// Fixer les paramètres de connexion public static function parametres($_dsn, $_user, $_pass) {     self::$dsn  = $_dsn ;     self::$user = $_user ;     self::$pass = $_pass ; 01:08:06 Programmation Web 2012-2013

Une implémentation /// Interdit le clonage du singleton public function __clone() {     throw new Exception("Clonage de ".__CLASS__." interdit !") ; } 01:08:06 Programmation Web 2012-2013

Simple, non ? Utilisation require_once "connexion.pdo.template.class.php" ; // Paramétrage du singleton myPDO::parametres('oci:dbname=bd11', 'scott', 'tiger') ; // Connexion automatique $pdostat = myPDO::donneInstance()->query( "SELECT * FROM Images") ; while (($ligne = $pdostat->fetch()) !== false) { echo $ligne['id']."<br>\n" ; } // Déconnexion automatique en fin de script Simple, non ? 01:08:06 Programmation Web 2012-2013

Raffinement possible : Débogage Possibilité d'afficher des messages informatifs pour se rendre compte de ce qu'il se passe et dépister les erreurs : connexion… requête… Cadre Web : comment afficher des informations qui ne perturbent pas l'affichage de la page commentaires HTML <!-- … --> doit pouvoir être désactivé  contenus non HTML Implémentation : attribut booléen statique et méthodes statiques 01:08:06 Programmation Web 2012-2013

Raffinement possible : Débogage Problème majeur, les méthodes de requête, préparation, etc sont des méthodes de l'objet PDO et non de myPDO Solution basique la méthode get retourne l'objet myPDO et non PDO l'objet myPDO doit implémenter toutes les méthodes de PDO qui consistent à lancer celles de PDO Solution "avancée" la méthode get() retourne l'objet myPDO et non PDO myPDO doit implémenter __call 01:08:06 Programmation Web 2012-2013

Une implémentation v2 /// Récupérer le singleton public static function donneInstance() {     self::msg("Recherche de l'instance...") ;     // Une instance est-elle disponible ?     if (!isset(self::$mypdo))         self::$mypdo = new myPDO() ;     self::msg("Instance trouvée") ;     // return self::$mypdo->pdo ;     return self::$mypdo ; } 01:08:06 Programmation Web 2012-2013

Une implémentation v2 /// Surcharge de toutes les méthodes indisponibles de myPDO pour pouvoir appeler celles de PDO public function __call($methodName/** Nom de la méthode */,                $methodArguments /** Tableau des paramètres */) {     // La méthode appelée fait-elle partie de la classe PDO     if (!method_exists($this->pdo, $methodName))         throw new Exception("PDO::$methodName n'existe pas") ;     // Message de debogage     self::msg("PDO::$methodName (".implode($methodArguments, ", ").")") ;     // Appel de la méthode avec l'objet PDO     $result = call_user_func_array( array($this->pdo, $methodName), $methodArguments) ;     return $result ; } 01:08:06 Programmation Web 2012-2013

Une implémentation v2 /// Affichage de messages de contrôle public static function msg($m /** Le message */) {     if (self::$debug)         Traceur::trace($m) ; } /// Mise en marche du debogage public static function debug_on() {     self::$debug = true ; /// Arrêt du debogage public static function debug_off() {     self::$debug = false ; 01:08:06 Programmation Web 2012-2013

Une implémentation v2 - 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:06 Programmation Web 2012-2013

Une implémentation v2 - 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:06 Programmation Web 2012-2013

Une implémentation v2 - 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:06 Programmation Web 2012-2013

Une implémentation v2 - 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:06 Programmation Web 2012-2013

Une implémentation v2 - Débogage Utilisation de la classe Traceur dans la classe myPDO : affichage des traces à la destruction /// Destructeur de myPDO public function __destruct() {     self::msg("Demande de destruction PDO...") ;     // S'il y a une connexion établie...     if (!is_null($this->pdo))     {         // ... il faut se deconnecter         self::msg("Demande de déconnexion...") ;         $this->pdo   = null ;         self::$mypdo = null ;         self::msg("Deconnexion effectuée") ;     }     self::msg("Destruction PDO terminée") ;    echo Traceur::affiche() ; } 01:08:06 Programmation Web 2012-2013

Raffinement possible : Débogage (suite) La solution est partielle : Les messages d'information concernent uniquement les méthodes de PDO Une requête préparée retourne un objet PDOStatement qui effectuera les méthodes bindValue, execute, fetch, … Comment tracer TOUTES les actions effectuées sur la base de données ?  Implémenter un objet myPDOStatement 01:08:06 Programmation Web 2012-2013

Une implémentation V3 /// Encapsulation de PDOStatement final class myPDOStatement {     /// L'objet PDOStatement     private $pdoStatement ;     /// Constructeur     public function __construct($_pdoStatement /** L'objet PDOStatement */) {         myPDO::msg("Construction PDOStatement") ;         $this->pdoStatement = $_pdoStatement ;     }     /// Destructeur     public function __destruct() {         myPDO::msg("Destruction PDOStatement") ;         $this->pdoStatement = null ; 01:08:06 Programmation Web 2012-2013

Une implémentation V3 /// Surcharge de toutes les méthodes indisponibles de myPDOStatement pour pouvoir appeler celles de PDOStatement public function __call($methodName/** Nom de la méthode */,                $methodArguments /** Tableau des paramètres */) {     // La méthode appelée fait-elle partie de la classe PDOStatement     if (!method_exists($this->pdoStatement, $methodName))         throw new Exception("PDOStatement::$methodName n'existe pas") ;     // Message de debogage     myPDO::msg("PDOStatement::".$methodName. " (".var_export($methodArguments, true).")") ;     // Appel de la méthode avec l'objet PDOStatement     return call_user_func_array( array($this->pdoStatement, $methodName), $methodArguments) ; } 01:08:06 Programmation Web 2012-2013

Une implémentation V3.1 Utilisation de myPDOStatement au lieu de PDOStatement ? public function __call($methodName/** Nom de la méthode */,                $methodArguments /** Tableau des paramètres */) {     // La méthode appelée fait-elle partie de la classe PDO     if (!method_exists($this->pdo, $methodName))         throw new Exception("PDO::$methodName n'existe pas") ;     // Message de debogage     self::msg("PDO::$methodName (".implode($methodArguments, ", ").")") ;     // Appel de la méthode avec l'objet PDO     $result = call_user_func_array( array($this->pdo, $methodName), $methodArguments) ;     return $result ; } // Selon le nom de la méthode switch ($methodName) { // Cas 'prepare' ou 'query' => fetchNamed case "prepare" : case "query" : $result->setFetchMode(PDO::FETCH_NAMED) ; // Retourne un objet myPDOStatement return new myPDOStatement($result) ; // Dans tous les autres cas default : // Retourne le résultat return $result ; } 01:08:06 Programmation Web 2012-2013

Aide au débogage, suite (et fin ?) error_reporting(E_ALL) ; /** Mise en place d'une capture des exceptions non attrapées */ function exceptionHandler($exception /** L'Exception non attrapée */) { echo "<pre>\n" ; echo $exception->getMessage()."\n" ; echo "Trace d'execution :\n" ; echo $exception->getTraceAsString() ; echo "</pre>\n" ; } set_exception_handler('exceptionHandler') ; 01:08:06 Programmation Web 2012-2013