Et avec PHP 5.4.0, nous avons droit aux traits. Les traits sont des bouts de code qui peuvent être réutilisés dans n'importe quelle classe. Vous trouverez ici tout ce que vous devez savoir sur les traits.
Objectif
Dans une premier temps je vais présenter (rapidement) le pattern singleton. En suite je vais décrire une méthode d'implémentation baseé sur les traits de PHP.Attention :
Utiliser des traits pour ce genre de technique à l'avantage de ne pas bloquer l'héritage d'un objet, tout en écrivant un code complet (en opposition aux interfaces, où le code doit être
Le pattern singleton est relativement simple a écrire, c'est pourquoi je trouve qu'il s'associe bien avec cette nouvelle fonctionnalité de PHP. Mais on peut rapidment écrire du code spaghetti avec le traits. C'est pourquoi je préconise de les utiliser seulement sur des comportements simples est clairs.
Le pattern singleton
Présentation
Le pattern singleton consiste à ne créer qu'une seule instance de classe et n'utiliser quelle dans toute l'application. L'exemple le plus courant est l'utilisation d'une classe "Db" pour la connexion à la base de données. C'est l'exemple que je vais prendre, et "Db" va étendre "PDO" pour plus de simplicité.
Plus besoin de se trimbaler une variable globale, où d'autres techniques douteuse pour récupérer la connexion, le code devient :
$db = Db::singleton();
ou encore
$count = Db::singleton()->exec("...");
Cette implémentation permet de passer des paramètres au constructeur si nécessaire.
Implémentation du pattern singleton
trait Singleton { /** * @ignore */ public static $instance = null; /** * Return the same instance of the class. * * @param mixed $args[optional] * @return object */ public static function singleton() { $class = new ReflectionClass(get_called_class()); $instance = $class->getProperty("instance"); if (is_null($instance->getValue())) { switch (func_num_args()) { case 0: $instance->setValue($class->newInstance()); break; default: $instance->setValue($class->newInstanceArgs(func_get_args())); } } return $instance->getValue(); } }
Utilisation de notre "trait"
Maintenant il suffit simplement de créer la "Db", de lui ajouter le trait "Singleton", de créer un constructeur avec des paramètres par défaut pour simplifier les choses.
class Db extends PDO { use Singleton; public function __construct($user = "USERNAME, $password = "PASSWORD") { $dsn = "mysql:host=DB_HOST;dbname=DB_NAME;charset=utf8"; parent::__construct($dsn, $user, $password); } }
Exemple d'utilisation sans arguments pour le constructeur:
$count = Db::singleton()->exec("..."); if ($count == 0) { ... }
Exmple d'utilisation où la connexion dépend de l'utilisateur connecté:
$count = Db::singleton($user->login, $user->password)->exec("..."); if ($count == 0) { ... }
Remarque: dans le deuxième cas, cela ne marche que si le premier appel à "Db::singleton()" se fait avec les paramètres, car uns fois l'instance crée elle est réutilisée.
Aucun commentaire:
Enregistrer un commentaire