Page 1 sur 1

Singleton PDO cherche amelioration

Posté : 12 sept. 2008, 10:50
par hi-logik
Bonjour à toutes et à tous ! :)

Voila je me met au design Pattern :D et je souhaite créer un class de connection SGBD singleton !

Je trouve cette methode interessante et j'ai observé pas mal de class sur le net et j'en ai trouvé une qui me correspond dans son style et je voudrais savoir ce que vous en pensé premièrement ?
voici le lien: http://www.apprendre-php.com/tutoriels/ ... _temp_url#

ensuite j'ai reproduite cette class et à la fin de ce tutoriel l'auteur cite :

<<Enfin, en redéfinissant les méthodes query() ou prepare() de PDO, vous aurez la possibilité d'ajouter un log des requêtes exécutées, etc. >>

à la base je n'arrive pas sans redefinir quoi que ce soit à me connecté grace à cette classe !


je penses qu'il faut utiliser l'instance getInstance genre SPDO::getInstance mais si je veux faire un query->($sql) ca ne marche pas !
je dois etre passé à coté de quelque chose ?


j'ai vu sur PHP France cette example très interessant aussi !

http://www.phpfrance.com/forums/voir_sujet-241515.php

et les remarque qu'il y à eu sont :

1) Tu n'utilises pas l'agument de ton constructeur.
2) Ton code serait plus simple si tu faisais hériter ta classe directement de la classe PDO (tu pourrais supprimer la variable $_handle).

Donc en faite je voudrais utilisé la 1er class citer plus avec les constantes et je voulais savoir si pour utiliser un query->($sql) par exemple, si je dois redefinir la class PDO dans la SPDO avec un extends ?

sachant que dans le constructeur de la class SPDO j'instancie PDO mais je ne sais pas comment acceder à ces methodes ?

Merci pour votre précieuse aide !

en faite je viens de trouver ! comme je ne peux pas repondre à mon propre message :( lool

j'ai redefini la methode query du genre :

Code : Tout sélectionner

public function query($statement) { return $this->PDOInstance->query($statement); }
en revanche est ce qu'il ne serais pas mieux d'hérité de la class PDO ?

si oui me conseillez vous de faire des modifications ?

Posté : 12 sept. 2008, 11:49
par doctorrock
Un héritage peut être pas mal ( après tout dépend de l'archi derrière hein).
Par exemple :
class MonPDOException extends PDOException { }

class MonPDO extends PDO
{
	private static $dsn  = 'mysql:host=localhost;dbname=test';
    private static $user = 'root';
    private static $pass = '';

	public function __construct()
	{
		try{
			parent::__construct(self::$dsn,self::$user,self::$pass);
			 $this->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		}catch (PDOException $e){
			throw new MonPDOException(__CLASS__ . ' a renvoyé une erreur : ' . $e->getMessage());
		}
	}
}

Singleton PDO

Posté : 12 sept. 2008, 14:18
par hi-logik
Bonjour et merci pour ta réactivité julien !

j'aime bien cette methode aussi !

cependant je cherche à faire un singleton pour etre sur que l'on instancie qu'une fois ?

et ton constructeur est public et je voudrais qu'il reste privé de facon à ce qu'on ne puisse pas l'instancié et obliger de passer par la methode public getInstance qui contien le test de svoir si l'instance existe déjà

si j'ai bien compris le singleton ?

alors dois je resté comme ca et ne pas herité de la classe PDO et donc je redefini les mehode PDO, ou bien y'a t'il un compromis d'après toi ?

Posté : 12 sept. 2008, 14:33
par doctorrock
Ben exercice tien : prend ma classe, et transforme la en singleton si c'est ce que tu veux :)

Singleton exercice lool

Posté : 12 sept. 2008, 15:31
par hi-logik
voici comment je veux faire ma class

Code : Tout sélectionner

class SPDO { /** * Instance de la classe PDO * * @var PDO * @acces private */ private $PDOInstance = null; /** * Instance de la class SPDO * * @var SPDO * @access private * @static */ private static $instance = null; /** * Constante: User name from the Database * @var String */ const USERNAME = 'root'; /** * Constante: Server host * @var String */ const HOST = 'localhost'; /** * Constante: Password * @var String */ const PASSWORD = ''; /** * Constante: Database name * @var String */ const DATABASE = 'agenda'; /** * Constructor * @param void * @return void * @see PDO::__construct() */ private function __construct() { try { $this->PDOInstance = new PDO('mysql:dbname='.self::DATABASE.';host='.self::HOST,self::USERNAME,self::PASSWORD); } catch (PDOException $e) { echo "Error :".$e->getMessage()."<br />"; } } /** * Create and return SPDO Object * * @access public * @static * @param void * @return SPDO $instance */ public static function getInstance() { if(is_null(self::$instance)) { self::$instance = new SPDO(); // si je met __CLASS__ ça ne marche pas } return self::$instance; } public function query($statement) { return $this->PDOInstance->query($statement); } } // quand j'instancie je fais ex: $connect = SPDO::getInstance(); puis $connect->query($sql);
j'aimerai employer ce model mais quand j'herite de la classe PDO ca me met une erreur typ:

fatal error Access level to SPDO::__construct must be public !
donc le constructeur doit etre public ok mais le pattern singleton doit etre private au niveau constructeur me semble t'il ?

c'est la ou je bloque !

Posté : 12 sept. 2008, 16:01
par doctorrock
Oui, tu peux pas hériter et transformer la visibilité en plus restrictif ( de public vers private par exemple), car tu brise l'héritage objet et les principes de l'OO :wink:

Tu ne peux donc hériter, et tu devras faire une composition, éventuellement avec un proxy de méthodes ^^

Singleton END

Posté : 12 sept. 2008, 16:16
par hi-logik
Merci pour ces explications qui m'aide beaucoup à avancer ! :D

et que me conseil tu ? ma methode est elle bonne ou mieux vaut que j'utilise la tienne ?

en terme de performance ou autre ?

ou bien les 2 ce valent et après c'est une question de choix ?

et puisque tu en parle et afin d'enrichir ma culture informatique ca veux dire quoi faire de la composition ? :roll:

Posté : 12 sept. 2008, 16:34
par doctorrock
http://julien-pauli.developpez.com/tuto ... agregator/ ^^

Tout est une question d'architecture logicielle

Singleton re encore moi ^^

Posté : 12 sept. 2008, 16:48
par hi-logik
Encore merci à toi Julien pour toutes ces informations je dormirais moin bete ce soir je te le garantie lool :D

je vais etudié ça de très près !

Je reviens encore lool je suis pas du genre à lacher l'affaire :D

je pense avoir compris les agrégations et je dirais que j'ai fais une composition puisque j'instancie l'objet PDO dans ma class !

mon code :

Code : Tout sélectionner

class SPDO { /** * Instance de la classe PDO * * @var PDO * @acces private */ private $PDOInstance = null; /** * Instance de la class SPDO * * @var SPDO * @access private * @static */ private static $instance = null; /** * Constante: User name from the Database * @var String */ const USERNAME = 'root'; /** * Constante: Server host * @var String */ const HOST = 'localhost'; /** * Constante: Password * @var String */ const PASSWORD = ''; /** * Constante: Database name * @var String */ const DATABASE = ''; /** * Constructor * @access private * @param void * @return void * @see PDO::__construct() */ private function __construct() { try { $this->PDOInstance = new PDO('mysql:dbname='.self::DATABASE.';host='.self::HOST,self::USERNAME,self::PASSWORD); $this->PDOInstance->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING); } catch (PDOException $e) { echo "<b>Error PDO:</b> ".$e->getMessage()."<br />\n"; } } /** * Empeche la copie externe de l'instance * @access private */ private function __clone() { throw new Exception('Le clonage de SPDO n\'est pas autoris&eacute;'); } /** * Create and return SPDO Object * * @access public * @static * @param void * @return SPDO $instance */ public static function getInstance() { if(is_null(self::$instance)) { self::$instance = new SPDO(); } return self::$instance; } /** * Executes an SQL statement, return the number of affected row * * @param <String> $statement * @return <int> */ public function exec($statement) { return $this->PDOInstance->exec($statement); } /** * * @param <String> $statement * @return <type> */ public function prepare($statement) { return $this->PDOInstance->prepare($statement); } /** * Executes an SQL statement, returning a result set as PDOStatement object * * @param <string> $statement * @return PDOStatement */ public function query($statement) { try { return $this->PDOInstance->query($statement); } catch (PDOException $e) { echo $e->getMessage(); } } /** * * @param <String> $statement * @return <type> */ public function queryFetchAllAssoc($statement) { return $this->PDOInstance->query($statement)->fetchAll(PDO::FETCH_ASSOC); } public function queryFetchAllObj($statement) { return $this->PDOInstance->query($statement)->fetchAll(PDO::FETCH_OBJ); } public function queryFetchAllBoth($statement) { return $this->query($statement)->fetchAll(PDO::FETCH_BOTH); } /** * @access public * @return <void> */ public function close() { $this->PDOInstance = null; } } ?>
désireux de suivre le singleton à la lettre j'ai donc décider de mettre mon constructeur private maintenant par rapport à tout ça je veux juste savoir si ma class est interessant par rapport au performance si je dois rajouter des exceptions ou tout autre idée ? est ce une bonne pratique ?

je fais une petite application gestionnaire de contact en objet à fin d'etudié et approndir mes connaissances en POO ! et je recherche de bon conseille car il me faut prendre de bonnes habitudes !

mon but avec cette classe c'est de m'en servir à chaque fois que je veux me connecté du coup je n'ai plus besoin de réecrire le driver et autre ! je pense que vous l'avez compris :)

merci pour votre aide !

Posté : 26 nov. 2008, 23:33
par simoh
juste pour plus d'informations un singleton est un patron de conception (design pattern) dont l'objet est de restreindre l'instanciation d'une classe à un seul objet