Php5 - instanciation unique de classe via multiton

Soyez le premier à donner votre avis sur cette source.

Snippet vu 7 841 fois - Téléchargée 29 fois


Contenu du snippet

Wowowow, avec un titre aussi compliqué je me demande comment vous avez fait pour venir jusqu'ici :)

Bon petite explication. J'ai developpé une petite classe grâce aux conseils avisés de la doc de php.net qui va me permettre d'instancier une seule fois la classe que je souhaite utiliser, et surtout que je puisse rendre mon objet global à tout mon projet.

J'utilise la méthode du Multiton (soit un Singleton mais version multiple) mais dans une classe à part. Voici donc ce que ca donne "codifiant parlant" :

Source / Exemple :


<?php
class ModInterface {

 public static $_instance = array();
 
 public static function GetInstance($name, $args = array()) {
 
  if ( !isset(self::$_instance[$name]) ) {
        if ( class_exists($name) ) {
		    
			// Création des arguments pour le constructeur de classe
		     $arglist = array();
			  for ($i = 0, $n = count($args); $i < $n; $i++) {
			      $arglist[] = '$args['.$i.']';
			  }
			 $arglist = implode(',', $arglist);
			 
			// Création d'une fonction temporaire pour l'instanciation de la classe
			$new_class = create_function('$name, $args', 'return new $name('.$arglist.');');
			define(strtoupper($name), NULL);
			self::$_instance[$name] = $new_class($name, $args);
		}
  }
  
  return self::$_instance[$name];

 }

}

// Voici donc la classe en elle-même. Maintenant, voyons comment je peux utiliser pour... par exemple... instancier ma base de donnée mysql.
// Ma base de donnée s'utilise avec une classe qui porte comme nom mysql. Exemple :

$mysql = ModInterface::GetInstance('mysql');
// Hop, je peux utiliser $mysql comme un objet qui va me servir pour ma base de donnée.
//$mysql->query();
//$mysql->fetch_row(); etc...

//On peut également utiliser $mysql dans une classe sans le faire passer en argument via le constructeur ! Exemple :
class x {
 public function __construct() {
  $mysql = ModInterface::GetInstance('mysql');
 }
}
// Non seulement je n'instancie mon objet qu'une seule fois, mais en plus je peux l'utiliser partout ! Gain d'exécution notable !!

// Je peux également faire passer des arguments à mon objet. Imaginons ceci :
class y {
 public function __construct($arg1, $arg2) { // }
}

Voici comment je peux instancier cet objet :
$y = ModInterface::GetInstance('y', array($arg1, $arg2));
//$y est un objet !

?>

Conclusion :


Voici donc comment instancier une seule fois son objet et l'utiliser partout dans son projet !

On peut même faire d'autres méthodes à ma classe d'interface aux cas d'une instanciation un peu différente (par exemple, en fonction du 'level' d'un membre pour appeler la bonne classe etc...)

Bref, plein de choses interessantes et qui reste sous controle !

Voila voila :)

J'ai oublié ceci :
N'oubliez pas dans vos classes de rajouter ceci dans votre constructeur :
if ( !defined(strtoupper(__CLASS__)) ) throw new Exception('Classe non appelé correctement');

Ca vous prémunira d'une instanciation douteuse :p

A voir également

Ajouter un commentaire Commentaires
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3
Bah en faite, cette méthode peut être appliquée pour chaque classe individuellement ! Hors la, je regroupe tous les Singletons de chaque classe.

Maintenant pourquoi une classe ? Parce que ma préférence va pour l'objet, voila tout :)
Maintenant, dans ma classe à moi, je n'ai pas que cette méthode car j'ai des classes qui s'instancient un peu différement :)
Messages postés
1293
Date d'inscription
mardi 9 novembre 2004
Statut
Membre
Dernière intervention
21 mai 2015

Sympa ce code... .. . ;o)

J'utilise le même concept hormis qu'il sagit d'une fonction et non d'une class et que les objets sont stockés dans une variable statique... ce qui au final revient un peut au même... juste que je vois pas l'interet de faire une class pour une seul méthode (mais c'est un avis perso)... .. .

9/10... .. . ;o)

@ tchaOo°
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3
Dans ma méthode statique, y'a ca :
define(strtoupper($name), NULL);

Ce qui fait que je défini une constante à ce moment la. Le nom de la constante étant le nom de la classe.
Donc à l'appel de mon constructeur, je regarde si la constante est initialisée !

Par contre, j'ai oublié quelque chose... c'est à dire le fait d'avoir instancier une classe via ModInterface::GetInstance() puis ensuite pouvoir faire : $x = new class;

Jvais corriger ca :)
Messages postés
3006
Date d'inscription
dimanche 14 avril 2002
Statut
Membre
Dernière intervention
31 décembre 2008

J'aime bcp le concept :) Et puis ça change ^^.

Tu dis:

if ( !defined(strtoupper(__CLASS__)) ) throw new Exception('Classe non appelé correctement');

mais comment pourrait-on appeler le constructeur d'une classe sans qu'elle soit définie? j'ai du mal ^^. mci!
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
22
C'est un très joli code :-)
Je testerai dès que possible dans un gros projet pour voir le gain.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.