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 :
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 />';
exit;
}
}
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 :
$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 : '.$method.' : '.$args[0].'';
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 static $req = array();
private $i = 0;
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 />';
exit;
}
}
public static function getInstance()
{
if(is_null(self::$instance))
{
self::$instance = new SPDO();
}
return self::$instance;
}
public function __call($method, $args = false)
{
self::$req[$this->i]['method'] = $method;
self::$req[$this->i]['args'] = trim($args[0]);
$this->i++;
return $this->PDOInstance->$method($args[0]);
}
public static function getReq()
{
return self::$req;
}
}
// Code ...
$req = SPDO::getReq();
foreach($req as $row)
{
echo $row['method'].' : '.$row['args'].'<br />';
}
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 :(