Singleton pour PDO - Apprendre-PHP.com

Rechercher
PHP5 Avancé - Eric Daspet et Cyril Pierre de Geyer - Commander sur Amazon.fr

Singleton pour PDO

Par Graphox -  5 reponses -  Le 11/04/2009 -  Flux RSS - 

Bonjour !

Tout d'abord je souhaite remercier  Emacs pour ces tutos sur la POO très bien expliqués :)

J'ai suivi le tuto sur le Singleton pour PDO et j'ai réussi à appliquer la méthode magique __call()

Voici ma class :

 

La class SPDO
class SPDO
{
 
private $PDOInstance = null;
 
private static $instance = null;
 
private function __construct()
{
try
{
$this->PDOInstance = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$this->PDOInstance->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
}
 
catch (PDOException $e)
{
echo 'Erreur ! : ' .$e->getMessage() . '<br />';
}
}
 
public static function getInstance()
{
if(is_null(self::$instance))
{
self::$instance = new SPDO();
}
 
return self::$instance;
}
 
 
public function __call($method, $args)
{
return $this->PDOInstance->$method($args[0]);
}
}

Et je l'utilise comme cela :

Utilisation de la class
$dbh = SPDO::getInstance();
 
// Exemple avec une requête d'insertion
$dbh->exec('
INSERT INTO auteur (nom, prenom)
VALUES ("Dupont", "Jean")
');

Ce que je voudrais savoir :

- Est-ce que la méthode __call marchera avec toutes les méthodes de PDO ? Etant donné que $args est un array, j'ai mis la clé à 0 et ça à l'air de marcher avec les méthodes courantes (exec, query, prepare, execute)

- Quel est l'avantage d'utiliser un singleton ? J'ai compris que c'était pour ne pas avoir 2 instances de PDO, mais si dans mon code je me connecte à MySQL via PDO 2 fois, quelle est la différence ?

 

Merci d'avance :)

Graphox.

PS : Ce site est super, les tutos de qualités, bonne continuation ;)

 

Réponses apportées à cette discussion

Par saturn1 -  Le 11/04/2009 - 

Ta méthode__call marchera pour toutes les méthodesPDO qui n'ont qu'un argument^^ :p

 

 
Par Graphox -  Le 12/04/2009 - 

Merci pour cette réponse !

Mais je viens de tester avec un

$stmt->BindValue(':nom', 'Test');

et ça fonctionne...

 De plus, j'ai rajouté ceci dans ma méthode __cal

echo 'Méthode : <strong>'.$method.'</strong> : <strong>'.$args[0].'</strong><hr />';

 Et je ne vois pas la méthode BindValue .. 

 

 
Par Graphox -  Le 13/04/2009 - 

Désolé du double post, je viens de comprendre :

les méthodes PDOStatement:: ne passe pas par la méthode __call car elles ne s'appliquent pas directement à $dbh.

 Donc comment faire pour obtenir un log des requêtes Execute, BindValue,..., ?

 Merci d'avance

 

 
Par Emacs -  Le 13/04/2009 - 

Il faut que tu te fasses une classe perso qui dérive PDOStatement. Et dans ton __call(), tu instancies et retourne cet objet par exemple pour pouvoir lui appliquer la méthode que tu veux appeler.

 
Par Graphox -  Le 13/04/2009 - 

Merci :)

 J'ai essayé mais en vain.

Je récupéres mes requêtes dans un tableau comme ceci :

  1. class SPDO
  2. {
  3. private static $req = array();
  4. private $i = 0;
  5. private $PDOInstance = null;
  6.  
  7. private static $instance = null;
  8.  
  9. private function __construct()
  10. {
  11. try
  12. {
  13. $this->PDOInstance = new PDO('mysql:host=localhost;dbname=test', 'root', '');
  14. $this->PDOInstance->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
  15. }
  16.  
  17. catch (PDOException $e)
  18. {
  19. echo 'Erreur ! : ' .$e->getMessage() . '<br />';
  20. }
  21. }
  22.  
  23. public static function getInstance()
  24. {
  25. if(is_null(self::$instance))
  26. {
  27. self::$instance = new SPDO();
  28. }
  29.  
  30. return self::$instance;
  31. }
  32.  
  33.  
  34. public function __call($method, $args = false)
  35. {
  36. self::$req[$this->i]['method'] = $method;
  37. self::$req[$this->i]['args'] = trim($args[0]);
  38. $this->i++;
  39. return $this->PDOInstance->$method($args[0]);
  40. }
  41.  
  42. public static function getReq()
  43. {
  44. return self::$req;
  45. }
  46. }
  47.  
  48. // Code ...
  49.  
  50. $req = SPDO::getReq();
  51.  
  52. foreach($req as $row)
  53. {
  54. echo $row['method'].' : '.$row['args'].'<br />';
  55. }

J'ai essayé de faire une classe extends PDOStatement, mais ça n'avait pas l'air de marcher (enfaite je ne sais pas trop quoi mettre dans cette classe à part un call, mais après comment l'instancier ..), et pour pouvoir compléter mon tableau, je me suis dit qu'il faudrait que cette classe hérite de SPDO ?

 Enfin je suis un peu perdu :(

 

Ajouter une réponse à la discussion

Seuls les membres loggués sont autorisés à poster dans les forums !