Classe Singleton Factory pour les fans de Singleton

ViPHP
ViPHP | 5462 Messages

18 févr. 2011, 17:17

Hello, voiçi une petite classe toute simple pour faire du Singleton avec n'importe quelle classe native à PHP,
il suffit de faire :
Singleton::NomDeLaClasse('les', 'parametres', 'du', '__construct')->LaMethode();
Une fois instancié vous pouvez toujours la récupérer via
Singleton::NomDeLaClasse()->LaMethode();
La classe Singleton (PHP 5.3) :
class Singleton
{
    protected static $_instances;
   
    public static function __callStatic($name, array $arguments)
    {    
        if(empty(static::$_instances[$name]) || !empty($arguments))
        {
        	if(strpos($name, '\\') === 0)
        	{
            	$name = substr($name, 1);
        	}
        	
        	$classname = '\\' . $name;

            if(method_exists($classname, '__construct'))
            {
                $class = new \ReflectionClass($classname);
                static::$_instances[$name] = $class->newInstanceArgs($arguments);
            }
            else
            {
                static::$_instances[$name] = new \$classname;
            }
        }

        return static::$_instances[$name];
    }
}
On pourrait appeler la class "_" pour plus de simplicité :
$dom = _::DOMDocument();
Modifié en dernier par stealth35 le 23 févr. 2011, 22:18, modifié 4 fois.

Eléphant du PHP | 383 Messages

18 févr. 2011, 22:58

Je n ai jamais vraiment compris le principe et l utilité d utilisation du Singleton. Un éclairage pas trop technique est-il possible ^^ ?
----------------------------------------------------------------------------------
www.april.org - Promouvoir et défendre le logiciel libre

ViPHP
ViPHP | 5462 Messages

18 févr. 2011, 23:23

Je n ai jamais vraiment compris le principe et l utilité d utilisation du Singleton. Un éclairage pas trop technique est-il possible ^^ ?
c'est pour éviter d'instancier un objet c'est plus court de faire :
$link = DOMDocument()->getInstance->loadHTMLFile($file)->getElementsByTagName('a');
que
$doc = new DOMDocument();
$link = $doc->loadHTMLFile($file)->getElementsByTagName('a');
de plus la classe fait aussi office de Registry :wink:

si tu veux plus d'info sur les design pattern : http://www.php.net/manual/fr/language.oop5.patterns.php
regarde surtout au niveau de Factory ca prend plus de sens

un très bon exemple est Doctrine ou pour récupérer par un utilisateur tu fera juste :
Doctrine_Core::getTable('user')->find(1);
on va dire que c'est de la simplification, pas besoin d'instancier X fois une base de données.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13234 Messages

19 févr. 2011, 01:32

C'est pas que ça "évite d'instancier l'objet", puisque l'instanciation se fait un interne.
C'est surtout que ça permet de travailler sur une unique instance (unique = single => singleton) de la classe. Quand il y a des couts important à l'instanciation (connexion à la base de données, par exemple), il est préférable de limiter le nombre d'instance, donc de passer par un singleton.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer