Bases de données Singleton pour la connexion Jérôme CUTRONA jerome.cutrona@univ-reims.fr 16:56:28 Programmation Web 2013-2014
Problématique 16:56:28 Programmation Web 2013-2014
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 à prévoir Quand doit-on se connecter, se déconnecter ? 16:56:28 Programmation Web 2013-2014
Solution classique : Singleton 16:56:28 Programmation Web 2013-2014
Singleton : objet à instance unique Réalisation : Solution : Singleton Singleton : objet à instance unique Instance unique => connexion unique Réalisation : 1 attribut statique Instance du Singleton 1 point d'accès méthode statique, gère l’unicité de l’instance limiter l'accès au constructeur privé / protégé interdire le clonage 16:56:28 Programmation Web 2013-2014
Solution : Singleton Adaptation à la connexion BD PDO : myPDO 1 attribut statique _PDOInstance, instance de PDO 1 point d'accès Méthode statique getInstance() Instanciation PDO si nécessaire => connexion constructeur privé Interdire la construction destructeur termine la connexion à la BD mise hors service de la méthode __clone throw new Exception("…") ; 16:56:28 Programmation Web 2013-2014
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::getInstance() 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 propre, transparent pour le développeur 16:56:28 Programmation Web 2013-2014
Implémentation 16:56:28 Programmation Web 2013-2014
Une implémentation <?php final class myPDO { private static $_PDOInstance = null ; private static $_DSN = null ; private static $_username = null ; private static $_password = null ; private static $_driverOptions = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ) ; 16:56:28 Programmation Web 2013-2014
Une implémentation public static function getInstance() { if (is_null(self::$_PDOInstance)) { if (self::hasConfiguration()) { self::$_PDOInstance = new PDO(self::$_DSN, self::$_username, self::$_password, self::$_driverOptions) ; } else { throw new Exception( __CLASS__ . ": Configuration not set") ; } return self::$_PDOInstance ; } 16:56:28 Programmation Web 2013-2014
Une implémentation private function __construct() { } private function __destruct() { if (!is_null(self::$_PDOInstance)) { self::$_PDOInstance = null ; } public function __clone() { throw new Exception("Clonage interdit") ; 16:56:28 Programmation Web 2013-2014
Gestion des paramètres de configuration 16:56:28 Programmation Web 2013-2014
Une implémentation public static function setConfiguration( $dsn, $username='', $password='', $driver_options=array()) { self::$_DSN = $dsn ; self::$_username = $username ; self::$_password = $password ; self::$_driverOptions = $driver_options + self::$_driverOptions ; } private static function hasConfiguration() { return self::$_DSN !== null ; 16:56:28 Programmation Web 2013-2014
Utilisation 16:56:28 Programmation Web 2013-2014
Simple, non ? Utilisation require_once "mypdo.class.php" ; myPDO::setConfiguration( 'mysql:host=mysql;dbname=my_db;charset=utf8', 'my_login', 'my_password') ; $pdo = myPDO::getInstance() ; $stmt = $pdo->prepare(<<<SQL SELECT id FROM a_table SQL ) ; $stmt->execute() ; while (($ligne = $stmt->fetch()) !== false) echo "<p>" . $ligne['id'] . "\n" ; // Déconnexion automatique en fin de script Simple, non ? 16:56:28 Programmation Web 2013-2014
Utilisation require_once "mypdo.class.php" ; myPDO::setConfiguration( 'mysql:host=mysql;dbname=my_db;charset=utf8', 'my_login', 'my_password') ; $pdo = myPDO::getInstance() ; $stmt = $pdo->prepare(<<<SQL SELECT id FROM a_table SQL ) ; $stmt->execute() ; while (($ligne = $stmt->fetch()) !== false) echo "<p>" . $ligne['id'] . "\n" ; // Déconnexion automatique en fin de script La configuration ne doit pas se trouver dans chaque fichier nécessitant un accès à la base de données 16:56:28 Programmation Web 2013-2014
Utilisation require_once "mypdo.class.php" ; myPDO::setConfiguration( 'mysql:host=mysql;dbname=my_db;charset=utf8', 'my_login', 'my_password') ; require_once "my_db.mypdo.class.php" ; $pdo = myPDO::getInstance() ; $stmt = $pdo->prepare(<<<SQL SELECT id FROM a_table SQL ) ; … Fichier de configuration my_db.mypdo.class.php 16:56:28 Programmation Web 2013-2014