Design Patterns: Singleton en PHP
Nous utilisons le design patterns singleton afin de limiter le nombre d’instances pouvant être créées à partir d’une classe consommatrice.
L’anatomie du pattern singleton
Commençons par comprendre les caractéristiques structurelles d’une classe qui suit le pattern singleton:
- Un constructeur privé est utilisé pour empêcher la création directe d’objets à partir de la classe.
- Le processus est effectué au sein du constructeur privé.
- La seule façon de créer une instance à partir de la classe est d’utiliser une méthode statique qui crée l’objet uniquement s’il n’a pas déjà été créé.
<?php class Singleton { // Gardez l'instance de classe. private static $instance = null; // Le constructeur est privé pour empêcher l'initiation. private function __construct() { // Mettez le processus de traitement ici. } /* L'objet est créé à partir de la classe elle-même uniquement si la classe n'a pas d'instance. */ public static function getInstance() { if (self::$instance == null) { self::$instance = new Singleton(); } return self::$instance; } } ?>
Comme nous limitons le nombre d’objets pouvant être créés à partir d’une classe à un seul, nous nous retrouvons avec toutes les variables pointant vers le même objet unique.
<?php // Toutes les variables pointent vers le même objet. $obj1 = Singleton::getInstance(); $obj2 = Singleton::getInstance(); $obj3 = Singleton::getInstance(); ?>
Exemple pratique: Connexion à une base de données
Regardons un exemple du pattern singleton avec une classe qui établit une connexion à une base de données et limite le nombre d’instances à une seule.
<?php // Singleton pour connecter au bd. class ConnexionBD { // Gardez l'instance de classe. private static $instance = null; private $conn; // La connexion au bd est établie dans le constructeur privé. private function __construct() { $this->conn = new PDO("mysql:host=localhost; dbname=test", "myuser", "mypassword"); } public static function getInstance() { if(!self::$instance) { self::$instance = new ConnexionBD(); } return self::$instance; } public function getConnection() { return $this->conn; } } ?>
Puisque nous utilisons une classe qui vérifie si une connexion existe déjà avant d’en établir une nouvelle, peu importe le nombre de fois où nous créons un nouvel objet à partir de la classe, nous obtenons toujours la même connexion.
<?php $instance = ConnexionBD::getInstance(); $conn = $instance->getConnection(); var_dump($conn); $instance = ConnexionBD::getInstance(); $conn = $instance->getConnection(); var_dump($conn); ?>
Le résultat est la même connexion pour les deux instances.