211 votes

Création du motif de conception Singleton en PHP5

Comment créer une classe Singleton en utilisant les classes PHP5?

270voto

nlaq Points 11379
 /**
 * 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 instance it
     *
     */
    private function __construct()
    {

    }
}
 

Utiliser:

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

$ fact == $ fact2;

Mais:

 $fact = new UserFactory()
 

Jette une erreur

123voto

mpartel Points 2365

Malheureusement, les réponses d'Inwdr se cassent lorsqu'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";
 

120voto

lnwdr Points 5557

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

 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, à savoir qu'avant PHP 5.3, toute classe qui étendait un Singleton produirait une instance de sa classe parente plutôt que 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.

26voto

Stefan Gehrig Points 47227

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 choses suivantes deviennent possibles

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

now $inst1 ! == $inst2 - ils ne sont plus les mêmes.

10voto

butchi Points 2001
 protected  static $_instance;

public static function getInstance()
{
    if(is_null(self::$_instance))
    {
        self::$_instance = new self();
    }
    return self::$_instance;
}
 

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X