PDO multiton et fonction personalisée.

Eléphant du PHP | 189 Messages

09 sept. 2009, 14:53

Bonjour à tous,

Toujours en quête d'apprentissage je me lance dans l'utilisation de la class PDO.

Je voudrais n'avoir qu'une instance de la class PDO tout comme je l'avais fait dans ma class Mysql, utilisant les fonction mysql_* .

J'ai donc crée une class multiton (MPDO) qui me permet de vérifier si une instance de PDO existe déjà, et si pas la crée.

Je peux donc avoir ce genre de code :
$www = MPDO::getInstance("beta_soez");

foreach ($www->pquery("SELECT id,pseudo FROM users") as $row) {
	echo $row['id']." ) ".$row['pseudo'] ."<br/>";
}

$denora = MPDO::getInstance("denora");

foreach ($denora->pquery("SELECT chanid,channel FROM chan") as $row) {
	echo $row['chanid']." ) ".$row['channel'] ."<br/>";
}


foreach ($www->pquery("SELECT id,pseudo FROM users") as $row) {
	echo $row['id']." ) ".$row['pseudo'] ."<br/>";
}

echo "<br/><br/>Nous avons fait : ".MPDO::nbrReq()." requètes en ".MPDO::time()." secondes";
Vu que mon site doit pouvoir se connecter à plusieurs base de données simultanément.

voiçi ma class :
<?

/*
Class MPDO permetant d'effectuer des requètes Mysql et retourner le résultat sous forme de tableau
-> Utilisation d'un multiton pour n'avoir qu'une instance de MPDO
*/


class MPDO {

	private static $instance = array();
	private static $dbinfo = Array();
	private static $time;
	private static $nb_req;
	private $pdo;
	
	/*
		Constructeur de notre class MPDO.
	*/
	
	private function __construct($dbname) {

		try {
			$this->pdo = new PDO(self::$dbinfo[$dbname]['dsn'], self::$dbinfo[$dbname]['user'], self::$dbinfo[$dbname]['pass']);
		}
		catch(PDOException $e) {
			echo 'Connexion échouée sur '.$dbname.' : ' . $e->getMessage() ;
		}
	}
	
	/*
		Fonction permetant de retourner la bonne instance de PDO en fonction de la base de donnée choissie.
	*/
	
	public function getInstance($dbname) {
	
		require_once(dirname(__FILE__)."/../db.inc.php");
		
		// Configue notre base de donnée
		if(empty(self::$dbinfo)) {
			self::$dbinfo = $db;
		}
		
		if(!array_key_exists($dbname,self::$dbinfo)) {
			throw new Exception('[MySql] given database name "'.$dbname.'" is not configured');
		}
		
		// Si l'instance de connexion à la base de donnees n'existe pas, creation puis ajout à la liste des instances
		if(!array_key_exists($dbname, self::$instance)) {
			self::$instance[$dbname] = new MPDO($dbname);
		}
		
		return self::$instance[$dbname];
	}
	/*
		Fonction qui envoi chaque méthodes passées à la class SPDO à notre instance PDO
	*/
	final public function __call($method, $args) {
	
		$debut = null;
		
		// Condition qui permet d'ajouter un timer à chaque exec ou query
		
		if( in_array($method,Array("query","exec")) ) {
			$debut = microtime(true);
		}
		
		$return = call_user_func_array(array($this->pdo,$method) , $args);
		
		if(!is_null($debut)) {
			$fin = microtime(true);
			self::$time = self::$time = self::$time + ($fin - $debut).
			self::$nb_req++;
		}
		
		return $return;

	}
	
	/*
		Fonction qui renvoi le nombre de requète
	*/
	public function nbrReq() {
		return self::$nb_req;
	}
	
	/*
		Fonction qui renvoi le temps passé pour chaque requète.
	*/
	public function time() {
		return round(self::$time,5);
	}

}
?>
Qu'en pensez-vous ?

J'avais dans un premier temps pensé à surcharger le class PDO pour avoir le compteur de requête et de temps, mais étant donnée que je n'ai pas accès au code de la méthode query et exec, il me semble que c'est impossible.



Merci pour votre avis !

A bientôt

ViPHP
ViPHP | 1136 Messages

10 sept. 2009, 10:00

Salut ,

Intéressant comme façon de faire , même si perso , je préfère utiliser des requêtes préparés , peut être dans les futures évolutions de ta classe ;-)

Sinon , au niveau de ces lignes :
if( in_array($method,Array("query","exec")) ) {
                        $debut = microtime(true);
                }
Ne faut il pas remplacer "query" par "pquery" ? car c'est la méthode que tu appels dans ton code .

Sinon , pour la connexion géré par PDO , je te conseil de remplacer ta gestion d'exception , par celle de PDO ,
$this->pdo = new PDO(self::$dbinfo[$dbname]['dsn'], self::$dbinfo[$dbname]['user'], self::$dbinfo[$dbname]['pass']);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Sinon , je pense que tu pouvais hériter de la classe PDO , et utiliser un fonctionnement similaire !

Bonne continuation ,

Ch.

Eléphant du PHP | 189 Messages

10 sept. 2009, 10:48

Salut
Bonjour, et merci pour ta réponse !

Ne faut il pas remplacer "query" par "pquery" ? car c'est la méthode que tu appels dans ton code .
Si, mais là, en locurence c'est une erreur de frappe.. En effet je souhaitais créer ma propre fonction, mais elle était inutile. Oublié de changer les appels
Sinon , pour la connexion géré par PDO , je te conseil de remplacer ta gestion d'exception , par celle de PDO
$this->pdo = new PDO(self::$dbinfo[$dbname]['dsn'], self::$dbinfo[$dbname]['user'], self::$dbinfo[$dbname]['pass']);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Je ne conaissais pas et alors ça.. Ca m'aide vraiment :-p
Sinon , je pense que tu pouvais hériter de la classe PDO , et utiliser un fonctionnement similaire !
Quel serait ici les avantages d'un héritage ?
Bonne continuation
Merci !!

ViPHP
ViPHP | 1136 Messages

10 sept. 2009, 11:07

Sinon , pour la connexion géré par PDO , je te conseil de remplacer ta gestion d'exception , par celle de PDO
$this->pdo = new PDO(self::$dbinfo[$dbname]['dsn'], self::$dbinfo[$dbname]['user'], self::$dbinfo[$dbname]['pass']);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Je ne conaissais pas et alors ça.. Ca m'aide vraiment :-p
Et bien celà permet de ne pas avoir à gérer les erreurs de connexions , car PDO le fait pour toi , avec les messages qui vont bien .

Maintenant , simule une erreur , et compare .. utilise celle qui te plait le plus :-)

Sinon , je pense que tu pouvais hériter de la classe PDO , et utiliser un fonctionnement similaire !
Quel serait ici les avantages d'un héritage ?
Et bien , ta classe aurait un accès aux méthodes est attributs de PDO , qui peut te faciliter la vie , si tu fais évoluer ta classe .


Ch.

Eléphant du PHP | 189 Messages

10 sept. 2009, 11:25

Quel serait ici les avantages d'un héritage ?
Et bien , ta classe aurait un accès aux méthodes est attributs de PDO , qui peut te faciliter la vie , si tu fais évoluer ta classe .
En effet, je n'avais pas vu ça comme ça..

Et donc au lieu d'un new je ferait un parent::construct et j'appelle les méthodes du père..

Encore du boulot :-D

Et sinon, point de vue code ma class te semble-t-elle bien faite ?
Je me suis mis à la POO il y a peu.. et a PDO il y a 2 jours


Merci pour tes réponses ;-)


Edit :

Ca ne marchera pas.. Je suis obligé du coup de définir mon constructeur en public. Et on peut donc instancier ma class sans le multiton..

Eléphanteau du PHP | 19 Messages

07 oct. 2009, 18:58

Et cette classe ! http://sourceforge.net/projects/phppdo/ elle est pas sympa ?
Celui qui recherche la vengeance devrait commencer par creuser 2 tomnes (Confucius)

Eléphant du PHP | 60 Messages

22 oct. 2017, 18:00

Bonjour,

Je déterre quelque peu le sujet, mais en suivant la procédure, j'ai un message d'erreur:
Strict standards: Non-static method MPDO::getInstance() should not be called statically in D:\wamp2\www\Multiton\index.php on line 5
Je peux ne pas faire afficher cette erreur mais bon, j'aimerais bien comprendre. :)
Merci!

EDIT> J'ai mis getInstance() en "public static" afin de ne plus avoir l'erreur, je ne sais pas si c'est la bonne solution...

ViPHP
ViPHP | 1136 Messages

22 oct. 2017, 20:29

Déterrer le sujet. ...
8 ans .... autant dire qu'un monde est passé depuis lol .