Le principe du design pattern (motif de conception) Singleton est qu’il permet à une classe de ne donner naissance qu’à une et une seule instance de cette classe. On ne peut donc disposer que d’un seul objet issu de cette classe dans un référentiel donné

L’exemple le plus classique d’utilisation d’un Singleton est une connexion à une base de données, une connexion doit être unique au sein d’une application.

<?php
trait Singleton
{
  /**
   * unique instance de classe
   */
   private static $instance = null;

   /**
    * Constructeur protected empêchant une instanciation en dehors de la classe elle-même
    */
  protected function __construct()
  {
  }

  /**
   * Pas de méthode magique permettant une duplication
   */
   protected function __clone()
   {
   }

   final public function __wakeup()
   {  
      trigger_error('Cet Objet est non deserialisable');
   }

   /**
    * Permet de récupérer l'unique instance
    * return static
    */  
    public static function getInstance() 
    {
        if (is_null(self::$instance)) {
            self::$instance = new static;
        }
        return self::$instance; 
    }

}

Dans cet exemple, le Singleton est représenté par un trait, ce qui permet de ne pas dupliquer le code dans chaque classe nécessitant cette fonctionnalité et de garder une possibilité d’héritage.

Afin de respecter le principe de ce motif de conception, la visibilité des méthodes magiques __construct, __clone et __wakeup est définie en protégé afin d’éviter respectivement : de pouvoir instancier directement l’objet, d’empêcher un éventuel clonage et enfin d’empêcher la dé-sérialisation de l’objet

Enfin une méthode statique getInstance permet de récupérer l’unique instance de l’objet représentée par une variable de visibilité privée $instance

Exemple d’utilisation

<?php
class Test 
{
    use Singleton;
}

 $test = new Test; // Affiche : Fatal error : Call to protected ....

 $a = Test::getInstance();
 $b = Test::getInstance();
var_dump($a===$b); // Affiche : bool(true)
 
 $c = unserialize(serialize($a)); // Affiche Fatal error : Cet objet est non ...

 $d = clone $a;
// Affiche : Fatal error : Call to protected A::__clone() from context ''

Si vous avez aimé, merci de partager avec vos amis 🙂

Référence