Question

Comment créer une classe Singleton à l'aide de classes PHP5?

Était-ce utile?

La solution

/**
 * Singleton class
 *
 */
final class UserFactory
{
    /**
     * Call this method to get singleton
     *
     * @return UserFactory
     */
    public static function Instance()
    {
        static $inst = null;
        if ($inst === null) {
            $inst = new UserFactory();
        }
        return $inst;
    }

    /**
     * Private ctor so nobody else can instantiate it
     *
     */
    private function __construct()
    {

    }
}

Pour utiliser:

$fact = UserFactory::Instance();
$fact2 = UserFactory::Instance();

$ fact == $ fact2;

Mais:

$fact = new UserFactory()

Lance une erreur.

Voir http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static pour comprendre les portées de variables statiques et pourquoi définir static $ inst = null; fonctionne.

Autres conseils

PHP 5.3 permet la création d'une classe Singleton pouvant être héritée via une liaison statique récente:

class Singleton
{
    protected static $instance = null;

    protected function __construct()
    {
        //Thou shalt not construct that which is unconstructable!
    }

    protected function __clone()
    {
        //Me not like clones! Me smash clones!
    }

    public static function getInstance()
    {
        if (!isset(static::$instance)) {
            static::$instance = new static;
        }
        return static::$instance;
    }
}

Cela résout le problème, car avant PHP 5.3, toute classe qui étendait un Singleton produirait une instance de sa classe mère au lieu de la sienne.

Maintenant, vous pouvez faire:

class Foobar extends Singleton {};
$foo = Foobar::getInstance();

Et $ foo sera une instance de Foobar au lieu d’une instance de Singleton.

Malheureusement, la réponse d'Inwdr se bloque quand il y a plusieurs sous-classes.

Voici une classe de base Singleton héritable correcte.

class Singleton
{
    private static $instances = array();
    protected function __construct() {}
    protected function __clone() {}
    public function __wakeup()
    {
        throw new Exception("Cannot unserialize singleton");
    }

    public static function getInstance()
    {
        $cls = get_called_class(); // late-static-bound class name
        if (!isset(self::$instances[$cls])) {
            self::$instances[$cls] = new static;
        }
        return self::$instances[$cls];
    }
}

Code de test:

class Foo extends Singleton {}
class Bar extends Singleton {}

echo get_class(Foo::getInstance()) . "\n";
echo get_class(Bar::getInstance()) . "\n";

La façon la plus simple et moderne de créer Singleton Pattern est la suivante:

<?php

/**
 * Singleton Pattern.
 * 
 * Modern implementation.
 */
class Singleton
{
    /**
     * Call this method to get singleton
     */
    public static function instance()
    {
      static $instance = false;
      if( $instance === false )
      {
        // Late static binding (PHP 5.3+)
        $instance = new static();
      }

      return $instance;
    }

    /**
     * Make constructor private, so nobody can call "new Class".
     */
    private function __construct() {}

    /**
     * Make clone magic method private, so nobody can clone instance.
     */
    private function __clone() {}

    /**
     * Make sleep magic method private, so nobody can serialize instance.
     */
    private function __sleep() {}

    /**
     * Make wakeup magic method private, so nobody can unserialize instance.
     */
    private function __wakeup() {}

}

Alors maintenant, vous pouvez l'utiliser comme.

<?php

/**
 * Database.
 *
 * Inherited from Singleton, so it's now got singleton behavior.
 */
class Database extends Singleton {

  protected $label;

  /**
   * Example of that singleton is working correctly.
   */
  public function setLabel($label)
  {
    $this->label = $label;
  }

  public function getLabel()
  {
    return $this->label;
  }

}

// create first instance
$database = Database::instance();
$database->setLabel('Abraham');
echo $database->getLabel() . PHP_EOL;

// now try to create other instance as well
$other_db = Database::instance();
echo $other_db->getLabel() . PHP_EOL; // Abraham

$other_db->setLabel('Priler');
echo $database->getLabel() . PHP_EOL; // Priler
echo $other_db->getLabel() . PHP_EOL; // Priler

Comme vous le voyez, cette réalisation est beaucoup plus flexible.

Vous devriez probablement ajouter une méthode privée __clone () pour interdire le clonage d'une instance.

private function __clone() {}

Si vous n'incluez pas cette méthode, les opérations suivantes sont possibles

$inst1=UserFactory::Instance(); // to stick with the example provided above
$inst2=clone $inst1;

maintenant $ inst1 ! == $ inst2 - ce n'est plus la même instance.

<?php
/**
 * Singleton patter in php
 **/
trait SingletonTrait {
   protected static $inst = null;

  /**
   * call this method to get instance
   **/
   public static function getInstance(){
      if (static::$inst === null){
         static::$inst = new static();
      }
      return static::$inst;
  }

  /**
   * protected to prevent clonning 
   **/
  protected function __clone(){
  }

  /**
   * protected so no one else can instance it 
   **/
  protected function __construct(){
  }
}

à utiliser:

/**
 *  example of class definitions using SingletonTrait
 */
class DBFactory {
  /**
   * we are adding the trait here 
   **/
   use SingletonTrait;

  /**
   * This class will have a single db connection as an example
   **/
  protected $db;


 /**
  * as an example we will create a PDO connection
  **/
  protected function __construct(){
    $this->db = 
        new PDO('mysql:dbname=foodb;port=3305;host=127.0.0.1','foouser','foopass');
  }
}
class DBFactoryChild extends DBFactory {
  /**
   * we repeating the inst so that it will differentiate it
   * from UserFactory singleton
   **/
   protected static $inst = null;
}


/**
 * example of instanciating the classes
 */
$uf0 = DBFactoryChild::getInstance();
var_dump($uf0);
$uf1 = DBFactory::getInstance();
var_dump($uf1);
echo $uf0 === $uf1;

respose:

object(DBFactoryChild)#1 (0) {
}
object(DBFactory)#2 (0) {
}

Si vous utilisez PHP 5.4: trait est une option, vous n'avez donc pas à gaspiller la hiérarchie des héritages pour avoir le Motif Singleton

et remarquez également que vous utilisiez traits ou étend Singleton L’un des problèmes était de créer un singleton de classes enfants si vous n’ajoutiez pas la ligne de code suivante:

   protected static $inst = null;

dans la classe enfant

le résultat inattendu sera:

object(DBFactoryChild)#1 (0) {
}
object(DBFactoryChild)#1 (0) {
}
protected  static <*>

Ce code peut s'appliquer à n'importe quelle classe sans se soucier de son nom.

instance; public static function getInstance() { if(is_null(self::<*>

Ce code peut s'appliquer à n'importe quelle classe sans se soucier de son nom.

instance)) { self::<*>

Ce code peut s'appliquer à n'importe quelle classe sans se soucier de son nom.

instance = new self(); } return self::<*>

Ce code peut s'appliquer à n'importe quelle classe sans se soucier de son nom.

instance; }

Ce code peut s'appliquer à n'importe quelle classe sans se soucier de son nom.

Prend en charge plusieurs objets avec 1 ligne par classe:

Cette méthode appliquera des singletons sur toutes les classes que vous souhaitez. Tout ce que vous avez à faire est d'ajouter une méthode à la classe pour laquelle vous souhaitez créer un singleton et le fera pour vous.

Ceci stocke également les objets dans un fichier "SingleTonBase". afin que vous puissiez déboguer tous vos objets que vous avez utilisés dans votre système en récursant les objets SingleTonBase .

Créez un fichier nommé SingletonBase.php et incluez-le à la racine de votre script!

Le code est

abstract class SingletonBase
{
    private static $storage = array();

    public static function Singleton($class)
    {
        if(in_array($class,self::$storage))
        {
            return self::$storage[$class];
        }
        return self::$storage[$class] = new $class();
    }
    public static function storage()
    {
       return self::$storage;
    }
}

Ensuite, pour chaque classe pour laquelle vous voulez créer un singleton, ajoutez simplement cette petite méthode unique.

public static function Singleton()
{
    return SingletonBase::Singleton(get_class());
}

Voici un petit exemple:

include 'libraries/SingletonBase.resource.php';

class Database
{
    //Add that singleton function.
    public static function Singleton()
    {
        return SingletonBase::Singleton(get_class());
    }

    public function run()
    {
        echo 'running...';
    }
}

$Database = Database::Singleton();

$Database->run();

Et vous pouvez simplement ajouter cette fonction singleton dans la classe que vous avez et elle ne créera qu'une instance par classe.

REMARQUE: vous devriez toujours rendre la __construct privée pour éliminer l'utilisation de new Class (); les instanciations.

class Database{

        //variable to hold db connection
        private $db;
        //note we used static variable,beacuse an instance cannot be used to refer this
        public static $instance;

        //note constructor is private so that classcannot be instantiated
        private function __construct(){
          //code connect to database  

         }     

         //to prevent loop hole in PHP so that the class cannot be cloned
        private function __clone() {}

        //used static function so that, this can be called from other classes
        public static function getInstance(){

            if( !(self::$instance instanceof self) ){
                self::$instance = new self();           
            }
             return self::$instance;
        }


        public function query($sql){
            //code to run the query
        }

    }


Access the method getInstance using
$db = Singleton::getInstance();
$db->query();

Vous n'avez pas vraiment besoin d'utiliser le motif Singleton, car il est considéré comme un anti-modèle. En gros, il y a beaucoup de raisons de ne pas appliquer ce modèle. Lisez ceci pour commencer: Meilleures pratiques pour les classes de singleton PHP .

Si après tout, vous pensez toujours que vous devez utiliser le modèle Singleton, nous pourrions écrire une classe qui nous permettra d'obtenir les fonctionnalités de Singleton en étendant notre classe abstraite SingletonClassVendor.

C’est ce que j’ai fait pour résoudre ce problème.

<?php
namespace wl;


/**
 * @author DevWL
 * @dosc allows only one instance for each extending class.
 * it acts a litle bit as registry from the SingletonClassVendor abstract class point of view
 * but it provides a valid singleton behaviour for its children classes
 * Be aware, the singleton pattern is consider to be an anti-pattern
 * mostly because it can be hard to debug and it comes with some limitations.
 * In most cases you do not need to use singleton pattern
 * so take a longer moment to think about it before you use it.
 */
abstract class SingletonClassVendor
{
    /**
     *  holds an single instance of the child class
     *
     *  @var array of objects
     */
    protected static $instance = [];

    /**
     *  @desc provides a single slot to hold an instance interchanble between all child classes.
     *  @return object
     */
    public static final function getInstance(){
        $class = get_called_class(); // or get_class(new static());
        if(!isset(self::$instance[$class]) || !self::$instance[$class] instanceof $class){
            self::$instance[$class] = new static(); // create and instance of child class which extends Singleton super class
            echo "new ". $class . PHP_EOL; // remove this line after testing
            return  self::$instance[$class]; // remove this line after testing
        }
        echo "old ". $class . PHP_EOL; // remove this line after testing
        return static::$instance[$class];
    }

    /**
     * Make constructor abstract to force protected implementation of the __constructor() method, so that nobody can call directly "new Class()".
     */
    abstract protected function __construct();

    /**
     * Make clone magic method private, so nobody can clone instance.
     */
    private function __clone() {}

    /**
     * Make sleep magic method private, so nobody can serialize instance.
     */
    private function __sleep() {}

    /**
     * Make wakeup magic method private, so nobody can unserialize instance.
     */
    private function __wakeup() {}

}

Exemple d'utilisation:

/**
 * EXAMPLE
 */

/**
 *  @example 1 - Database class by extending SingletonClassVendor abstract class becomes fully functional singleton
 *  __constructor must be set to protected becaouse: 
 *   1 to allow instansiation from parent class 
 *   2 to prevent direct instanciation of object with "new" keword.
 *   3 to meet requierments of SingletonClassVendor abstract class
 */
class Database extends SingletonClassVendor
{
    public $type = "SomeClass";
    protected function __construct(){
        echo "DDDDDDDDD". PHP_EOL; // remove this line after testing
    }
}


/**
 *  @example 2 - Config ...
 */
class Config extends SingletonClassVendor
{
    public $name = "Config";
    protected function __construct(){
        echo "CCCCCCCCCC" . PHP_EOL; // remove this line after testing
    }
}

Juste pour prouver que cela fonctionne comme prévu:

/**
 *  TESTING
 */
$bd1 = Database::getInstance(); // new
$bd2 = Database::getInstance(); // old
$bd3 = Config::getInstance(); // new
$bd4 = Config::getInstance(); // old
$bd5 = Config::getInstance(); // old
$bd6 = Database::getInstance(); // old
$bd7 = Database::getInstance(); // old
$bd8 = Config::getInstance(); // old

echo PHP_EOL."COMPARE ALL DATABASE INSTANCES".PHP_EOL;
var_dump($bd1);
echo '$bd1 === $bd2' . ($bd1 === $bd2)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd2 === $bd6' . ($bd2 === $bd6)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd6 === $bd7' . ($bd6 === $bd7)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE

echo PHP_EOL;

echo PHP_EOL."COMPARE ALL CONFIG INSTANCES". PHP_EOL;
var_dump($bd3);
echo '$bd3 === $bd4' . ($bd3 === $bd4)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd4 === $bd5' . ($bd4 === $bd5)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd5 === $bd8' . ($bd5 === $bd8)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE

Toute cette complexité ("liaison statique tardive" ... harumph) est pour moi tout simplement un signe du modèle objet / classe brisé de PHP. Si les objets de classe étaient des objets de première classe (voir Python), alors "$ _ instance". serait une variable de classe instance - un membre de l'objet de classe, par opposition à un membre / propriété de ses instances, et également opposé à partagé par ses descendants. Dans le monde Smalltalk, c’est la différence entre une "variable de classe" et une "variable d'instance de classe".

En PHP, il me semble qu’il faut prendre à cœur que les modèles sont un guide pour l’écriture de code - on pourrait peut-être penser à un modèle Singleton, mais essayer d’écrire du code qui hérite d’une ; Singleton " La classe semble mal orientée pour PHP (bien que je suppose qu'une âme entreprenante puisse créer un mot clé SVN approprié).

Je continuerai à coder chaque singleton séparément, à l'aide d'un modèle partagé.

Remarquez que je reste absolument HORS des discussions singletons-sont-diaboliques, la vie est trop courte.

Je sais que cela va probablement provoquer une guerre de flammes inutile, mais je vois bien comment vous pourriez vouloir plus d'une connexion à une base de données. Je concède donc que singleton n'est peut-être pas la meilleure solution pour cela ... cependant , il existe d’autres utilisations du motif singleton que je trouve extrêmement utiles.

En voici un exemple: j’ai décidé de lancer mon propre moteur MVC et de modélisation, car je voulais quelque chose de vraiment léger. Cependant, les données que je souhaite afficher contiennent de nombreux caractères mathématiques spéciaux, tels que & # 8805; et & # 956; et qu'avez-vous ... Les données sont stockées en tant que caractère UTF-8 dans ma base de données plutôt qu'encodées au préalable en HTML, car mon application peut fournir d'autres formats tels que PDF et CSV en plus du HTML. L'endroit approprié pour formater HTML est à l'intérieur du modèle ("vue" si vous le souhaitez) responsable du rendu de cette section de page (extrait). Je veux les convertir en entités HTML appropriées, mais la fonction get_html_translation_table () des PHP n'est pas très rapide. Il est plus judicieux de récupérer les données une fois et de les stocker sous forme de tableau, afin de les rendre accessibles à tous. Voici un échantillon que j'ai frappé ensemble pour tester la vitesse. Cela fonctionnerait vraisemblablement, que les autres méthodes utilisées (après avoir obtenu l'instance) soient statiques ou non.

class EncodeHTMLEntities {

    private static $instance = null;//stores the instance of self
    private $r = null;//array of chars elligalbe for replacement

    private function __clone(){
    }//disable cloning, no reason to clone

    private function __construct()
    {
        $allEntities = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES);
        $specialEntities = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES);
        $this->r = array_diff($allEntities, $specialEntities);
    }

    public static function replace($string)
    {
        if(!(self::$instance instanceof self) ){
            self::$instance = new self();
        }
        return strtr($string, self::$instance->r);
    }
}
//test one million encodings of a string
$start = microtime(true);
for($x=0; $x<1000000; $x++){
    $dump = EncodeHTMLEntities::replace("Reference method for diagnosis of CDAD, but clinical usefulness limited due to extended turnaround time (≥96 hrs)");
}
$end = microtime(true);
echo "Run time: ".($end-$start)." seconds using singleton\n";
//now repeat the same without using singleton
$start = microtime(true);
for($x=0; $x<1000000; $x++){
    $allEntities = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES);
    $specialEntities = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES);
    $r = array_diff($allEntities, $specialEntities);
    $dump = strtr("Reference method for diagnosis of CDAD, but clinical usefulness limited due to extended turnaround time (≥96 hrs)", $r);
}
$end = microtime(true);
echo "Run time: ".($end-$start)." seconds without using singleton";

En gros, j’ai vu des résultats typiques comme celui-ci:

php test.php
Run time: 27.842966794968 seconds using singleton
Run time: 237.78191494942 seconds without using singleton

Donc, même si je ne suis certainement pas un expert, je ne vois pas de moyen plus pratique et plus fiable de réduire le temps système des appels lents pour certaines données, tout en simplifiant les choses (simple ligne de code pour faire ce que vous voulez. avoir besoin). Certes, mon exemple n’a qu’une méthode utile, et n’est donc pas meilleur qu’une fonction définie globalement, mais dès que vous aurez deux méthodes, vous voudrez les regrouper, n’est-ce pas? Suis-je bien en dehors de la base?

De plus, je préfère les exemples qui font réellement quelque chose, car il est parfois difficile de visualiser lorsqu'un exemple inclut des instructions telles que "// fait quelque chose d'utile ici". que je vois tout le temps lors de la recherche de tutoriels.

Quoi qu’il en soit, je serais ravi de recevoir vos réactions et commentaires sur les raisons pour lesquelles l’utilisation d’un singleton pour ce type de chose est préjudiciable (ou excessivement compliquée).

Cet article traite de manière assez détaillée du sujet: http://www.phptherightway.com/pages/Design-Patterns.html#singleton

  

Notez les éléments suivants:

     
      
  • Le constructeur __ construct () est déclaré comme protected afin d'empêcher la création d'une nouvelle instance en dehors de la classe via l'opérateur new .
  •   
  • La méthode magique __ clone () est déclarée comme privé pour empêcher le clonage d'une instance de la classe via l'opérateur clone .
  •   
  • La méthode magique __ wakeup () est déclarée comme privé pour empêcher la désérialisation d'une instance de la classe via la fonction globale.    unserialize () .
  •   
  • Une nouvelle instance est créée via une liaison statique tardive dans la méthode de création statique getInstance () avec le mot clé static . Ce   permet le sous-classement de la classe Singleton dans l'exemple.
  •   

J'ai écrit longtemps pensé à partager ici

class SingletonDesignPattern {

    //just for demo there will be only one instance
    private static $instanceCount =0;

    //create the private instance variable
    private static $myInstance=null;

    //make constructor private so no one create object using new Keyword
    private function  __construct(){}

    //no one clone the object
    private function  __clone(){}

    //avoid serialazation
    public function __wakeup(){}

    //ony one way to create  object
    public static  function  getInstance(){

        if(self::$myInstance==null){
            self::$myInstance=new SingletonDesignPattern();
            self::$instanceCount++;
        }
        return self::$myInstance;
    }

    public static function getInstanceCount(){
        return self::$instanceCount;
    }

}

//now lets play with singleton design pattern

$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();

echo "number of instances: ".SingletonDesignPattern::getInstanceCount();

Je suis d’accord avec la première réponse, mais j’aimerais également déclarer la classe finale afin qu’elle ne puisse pas être étendue car l’extension d’un singleton viole le modèle singleton. De plus, la variable d'instance doit être privée afin de ne pas pouvoir y accéder directement. Assurez-vous également que la méthode __clone est privée afin que vous ne puissiez pas cloner l'objet singleton.

Vous trouverez ci-dessous un exemple de code.

/**
 * Singleton class
 *
 */
final class UserFactory
{
    private static 

Je suis d’accord avec la première réponse, mais j’aimerais également déclarer la classe finale afin qu’elle ne puisse pas être étendue car l’extension d’un singleton viole le modèle singleton. De plus, la variable d'instance doit être privée afin de ne pas pouvoir y accéder directement. Assurez-vous également que la méthode __clone est privée afin que vous ne puissiez pas cloner l'objet singleton.

Vous trouverez ci-dessous un exemple de code.

$user_factory = UserFactory::getInstance();

Exemple d'utilisation

$user_factory = UserFactory::

Je suis d’accord avec la première réponse, mais j’aimerais également déclarer la classe finale afin qu’elle ne puisse pas être étendue car l’extension d’un singleton viole le modèle singleton. De plus, la variable d'instance doit être privée afin de ne pas pouvoir y accéder directement. Assurez-vous également que la méthode __clone est privée afin que vous ne puissiez pas cloner l'objet singleton.

Vous trouverez ci-dessous un exemple de code.

/**
 * Singleton class
 *
 */
final class UserFactory
{
    private static 

Je suis d’accord avec la première réponse, mais j’aimerais également déclarer la classe finale afin qu’elle ne puisse pas être étendue car l’extension d’un singleton viole le modèle singleton. De plus, la variable d'instance doit être privée afin de ne pas pouvoir y accéder directement. Assurez-vous également que la méthode __clone est privée afin que vous ne puissiez pas cloner l'objet singleton.

Vous trouverez ci-dessous un exemple de code.

$user_factory = UserFactory::getInstance();

Exemple d'utilisation

<*>

Qu'est-ce que cela vous empêche de faire (ce qui violerait le motif singleton ..

VOUS NE POUVEZ PAS FAIRE CECI!

<*>instance = null; /** * Private constructor * */ private function __construct() {} /** * Private clone method * */ private function __clone() {} /** * Call this method to get singleton * * @return UserFactory */ public static function getInstance() { if (self::

Je suis d’accord avec la première réponse, mais j’aimerais également déclarer la classe finale afin qu’elle ne puisse pas être étendue car l’extension d’un singleton viole le modèle singleton. De plus, la variable d'instance doit être privée afin de ne pas pouvoir y accéder directement. Assurez-vous également que la méthode __clone est privée afin que vous ne puissiez pas cloner l'objet singleton.

Vous trouverez ci-dessous un exemple de code.

<*>

Exemple d'utilisation

<*>

Qu'est-ce que cela vous empêche de faire (ce qui violerait le motif singleton ..

VOUS NE POUVEZ PAS FAIRE CECI!

<*>instance === null) { self::

Je suis d’accord avec la première réponse, mais j’aimerais également déclarer la classe finale afin qu’elle ne puisse pas être étendue car l’extension d’un singleton viole le modèle singleton. De plus, la variable d'instance doit être privée afin de ne pas pouvoir y accéder directement. Assurez-vous également que la méthode __clone est privée afin que vous ne puissiez pas cloner l'objet singleton.

Vous trouverez ci-dessous un exemple de code.

<*>

Exemple d'utilisation

<*>

Qu'est-ce que cela vous empêche de faire (ce qui violerait le motif singleton ..

VOUS NE POUVEZ PAS FAIRE CECI!

<*>instance = new UserFactory(); } return self::

Je suis d’accord avec la première réponse, mais j’aimerais également déclarer la classe finale afin qu’elle ne puisse pas être étendue car l’extension d’un singleton viole le modèle singleton. De plus, la variable d'instance doit être privée afin de ne pas pouvoir y accéder directement. Assurez-vous également que la méthode __clone est privée afin que vous ne puissiez pas cloner l'objet singleton.

Vous trouverez ci-dessous un exemple de code.

<*>

Exemple d'utilisation

<*>

Qu'est-ce que cela vous empêche de faire (ce qui violerait le motif singleton ..

VOUS NE POUVEZ PAS FAIRE CECI!

<*>instance; } }

Exemple d'utilisation

<*>

Qu'est-ce que cela vous empêche de faire (ce qui violerait le motif singleton ..

VOUS NE POUVEZ PAS FAIRE CECI!

<*>instance; class SecondUserFactory extends UserFactory { }

Qu'est-ce que cela vous empêche de faire (ce qui violerait le motif singleton ..

VOUS NE POUVEZ PAS FAIRE CECI!

<*>instance = null; /** * Private constructor * */ private function __construct() {} /** * Private clone method * */ private function __clone() {} /** * Call this method to get singleton * * @return UserFactory */ public static function getInstance() { if (self::

Je suis d’accord avec la première réponse, mais j’aimerais également déclarer la classe finale afin qu’elle ne puisse pas être étendue car l’extension d’un singleton viole le modèle singleton. De plus, la variable d'instance doit être privée afin de ne pas pouvoir y accéder directement. Assurez-vous également que la méthode __clone est privée afin que vous ne puissiez pas cloner l'objet singleton.

Vous trouverez ci-dessous un exemple de code.

<*>

Exemple d'utilisation

<*>

Qu'est-ce que cela vous empêche de faire (ce qui violerait le motif singleton ..

VOUS NE POUVEZ PAS FAIRE CECI!

<*>instance === null) { self::

Je suis d’accord avec la première réponse, mais j’aimerais également déclarer la classe finale afin qu’elle ne puisse pas être étendue car l’extension d’un singleton viole le modèle singleton. De plus, la variable d'instance doit être privée afin de ne pas pouvoir y accéder directement. Assurez-vous également que la méthode __clone est privée afin que vous ne puissiez pas cloner l'objet singleton.

Vous trouverez ci-dessous un exemple de code.

<*>

Exemple d'utilisation

<*>

Qu'est-ce que cela vous empêche de faire (ce qui violerait le motif singleton ..

VOUS NE POUVEZ PAS FAIRE CECI!

<*>instance = new UserFactory(); } return self::

Je suis d’accord avec la première réponse, mais j’aimerais également déclarer la classe finale afin qu’elle ne puisse pas être étendue car l’extension d’un singleton viole le modèle singleton. De plus, la variable d'instance doit être privée afin de ne pas pouvoir y accéder directement. Assurez-vous également que la méthode __clone est privée afin que vous ne puissiez pas cloner l'objet singleton.

Vous trouverez ci-dessous un exemple de code.

<*>

Exemple d'utilisation

<*>

Qu'est-ce que cela vous empêche de faire (ce qui violerait le motif singleton ..

VOUS NE POUVEZ PAS FAIRE CECI!

<*>instance; } }

Exemple d'utilisation

<*>

Qu'est-ce que cela vous empêche de faire (ce qui violerait le motif singleton ..

VOUS NE POUVEZ PAS FAIRE CECI!

<*>

Cela devrait être la bonne façon de Singleton.

class Singleton {

    private static $instance;
    private $count = 0;

    protected function __construct(){

    }

    public static function singleton(){

        if (!isset(self::$instance)) {

            self::$instance = new Singleton;

        }

        return self::$instance;

    }

    public function increment()
    {
        return $this->count++;
    }

    protected function __clone(){

    }

    protected function __wakeup(){

    }

} 

J'ai aimé la méthode d'utilisation des traits @ jose-segura, mais je n'ai pas aimé la nécessité de définir une variable statique sur les sous-classes. Voici une solution qui l’évite en mettant en cache les instances dans une variable locale statique avec la méthode fabrique indexée par nom de classe:

<?php
trait Singleton {

  # Single point of entry for creating a new instance. For a given
  # class always returns the same instance.
  public static function instance(){
    static $instances = array();
    $class = get_called_class();
    if( !isset($instances[$class]) ) $instances[$class] = new $class();
    return $instances[$class];
  }

  # Kill traditional methods of creating new instances
  protected function __clone() {}
  protected function __construct() {}
}

L'utilisation est la même que @ jose-segura, mais il n'est pas nécessaire d'utiliser la variable statique dans les sous-classes.

La classe de base de données qui vérifie s’il existe une instance de base de données, elle retournera l’instance précédente.

   class Database {  
        public static $instance;  
         public static function getInstance(){  
            if(!isset(Database::$instance) ) {  
                Database::$instance = new Database();  
            }  
           return Database::$instance;  
         }  
         private function __cunstruct() {  
           /* private and cant create multiple objects */  
         }  
         public function getQuery(){  
            return "Test Query Data";  
         }  
    }  
    $dbObj = Database::getInstance();  
    $dbObj2 = Database::getInstance();  
    var_dump($dbObj);  
    var_dump($dbObj2);  


/* 
After execution you will get following output: 

object(Database)[1] 
object(Database)[1] 

*/  

Référez-vous http://www.phptechi.com/php-singleton -design-patterns-example.html

Ceci est l'exemple de create singleton sur la classe Database

modèles de conception 1) singleton

class Database{
  public static $instance;
  public static function getInstance(){
    if(!isset(Database::$instance)){
    Database::$instance=new Database();

     return Database::$instance;
    }

  }

  $db=Database::getInstance();
  $db2=Database::getInstance();
  $db3=Database::getInstance();

  var_dump($db);
  var_dump($db2);
  var_dump($db3);

alors dehors mis est -

  object(Database)[1]
  object(Database)[1]
  object(Database)[1]

utiliser seulement une instance ne pas créer une instance 3

Voici mon exemple qui permet d'appeler en tant que $ var = new Singleton () et de créer 3 variables pour vérifier s'il crée un nouvel objet:

class Singleton{

    private static $data;

    function __construct(){
        if ($this::$data == null){
            $this->makeSingleton();
        }
        echo "<br/>".$this::$data;
    }

    private function makeSingleton(){
        $this::$data = rand(0, 100);
    }

    public function change($new_val){
        $this::$data = $new_val;
    }

    public function printme(){
        echo "<br/>".$this::$data;
    }

}


$a = new Singleton();
$b = new Singleton();
$c = new Singleton();

$a->change(-2);
$a->printme();
$b->printme();

$d = new Singleton();
$d->printme();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top