Singleton pour PDO
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 SPDOclass SPDO{private $PDOInstance = 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){exit;}}{{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
Ta méthode__call marchera pour toutes les méthodesPDO qui n'ont qu'un argument^^ :p
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 ..
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
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.
Merci :)
J'ai essayé mais en vain.
Je récupéres mes requêtes dans un tableau comme ceci :
class SPDO { private $i = 0; private $PDOInstance = 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) { exit; } } { { self::$instance = new SPDO(); } return self::$instance; } public function __call($method, $args = false) { self::$req[$this->i]['method'] = $method; $this->i++; return $this->PDOInstance->$method($args[0]); } { return self::$req; } } // Code ... $req = SPDO::getReq(); foreach($req as $row) { }
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 :(
