Page 1 sur 6

Classes "extendue" de PDO

Posté : 25 nov. 2006, 10:33
par jojolapine
Bonjour à tous,
je voudrai savoir si il est possible de faire une classe de la classe PDO,
et ceci à fin de mettre en place un compteur de requête entre autre (sauf si cette fonctionnalité éxiste déja dans la classe PDO ?)
Et donc si c'était possible, je voulais savoir si ma méthode était bonne...
voilà comment je pense faire:
class SQL extends PDO {

  //initialisation d'une variable de contage
  private $nbrQuery=0;

  //redéfinition des classes de PDO

  function query(/*arguments*/){
    parent::query(/*arguments*/);
    $this->nbrQuery++;
  }

  //faire de même avec les autres fonctions qui effectues des requêtes
}
Voilà si vous pensez que c'est bien pas bien ou si vous avez mieu à proposer ?
merci d'avance
edit, j'ai oublié de mettre la fonction qui donne le nombre de requête:
function getnbrQuery(){
// je mettrai éventuellement une variable en option pour avoir les différences en tre requête directe préparée...
  return $this->nbrQuery;
}

Posté : 25 nov. 2006, 11:01
par Cyrano
Salut,

Je ne sais pas si la méthode est valable. En revanche, je note un détail : si tu fais du PHP5, alors tes méthodes doivent avoir un indicateur de niveau d'accès : public, private ou protected. Ensuite, je ne saurais trop te recommander de commenter soigneusement ton code systématiquement.

Exemple sur la base de ton code :
<?php
/**
 * Compteur de requêtes.
 *
 * Classe étendue de PDO destinée à compter le nombre de requêtes envoyées.
 */
class SQL extends PDO
{
    /**
     * initialisation d'une variable de comptage
     *
     * @var Int
     */
    private $nbrQuery = 0;

    /**
     * redéfinition des méthodes de PDO.
     * Chaque méthode utilisant une requête SQL incrémentera le compteur.
     * 
     * @todo faire de même avec les autres fonctions qui effectuent des requêtes.
     */
    
    /**
     * Redéfinition de la methode parent::query()
     */
    public function query(/*arguments*/)
    {
        parent::query(/*arguments*/);
        $this->nbrQuery++;
    }

    /**
     * Récupération du nombre de requêtes.
     *
     * @return Int
     */
    public function getnbrQuery()
    {
        /* je mettrai éventuellement une variable en option pour avoir 
           les différences en tre requête directe préparée. */
        return $this->nbrQuery;
    }
}
?>

Posté : 25 nov. 2006, 13:49
par jojolapine
merci pour ta réponse Cyrano, et effectivement je n'ai pas commenté mon code, mais (c'est pas une excuse d'accord... :oops: ) c'était juste au niveau méthode...
D'ailleur qu'entends tu par je ne sais pas si la méthode est valable ?
ça ne fonctionnera pas?
on peu faire mieu?
c'est peut-être un peu long de se redéfinir toutes les méthodes qui éxécute des requêtes ?
Sinon, quelle méthode utilisez-vous si vous avez déja essayé de faire cela?

Posté : 25 nov. 2006, 14:04
par momox
merci pour ta réponse Cyrano, et effectivement je n'ai pas commenté mon code, mais (c'est pas une excuse d'accord... :oops: ) c'était juste au niveau méthode...
D'ailleur qu'entends tu par je ne sais pas si la méthode est valable ?
ça ne fonctionnera pas?
on peu faire mieu?
c'est peut-être un peu long de se redéfinir toutes les méthodes qui éxécute des requêtes ?
Sinon, quelle méthode utilisez-vous si vous avez déja essayé de faire cela?
Comme on dit, pour voir si ca marche, ya qu'a tester !

Posté : 25 nov. 2006, 14:42
par Ajoloca
Bonjour,
je voudrai savoir si il est possible de faire une classe de la classe PDO
Je pense que oui, elle n'est pas défine comme "final".
mettre en place un compteur de requête entre autre
Une première remarque, la notion de "query" avec PDO n'est pas la même que avec les méthodes classiques (mysql_query, mysqli_query)
Elle ne concerne que les requêtes qui retournent un résultat (données) comme "SELECT, EXPLAIN, SHOW et DESC" (j'en oublie PTT mais la notion est là). Ce qui veux dire que celles qui executent une action dans la base "INSERT, DELETE, UPDATE,..." ne sont pas concernées, c'est la méthode "execute()".
sauf si cette fonctionnalité éxiste déja dans la classe PDO
Pas à ma connaissance
si tu fais du PHP5
Il est bien obligé, PDO n'existe que depuis cette version.
tes méthodes doivent avoir un indicateur de niveau d'accès
Je dirais comme toi pour la bonne structuration et compréhension du code (écriture propre) mais la bonté de PHP fait que s'il n'y-a pas de de niveau spécifié c'est "public" qui est pris par défaut (je l'ilustre plus bas).
je ne saurais trop te recommander de commenter soigneusement ton code systématiquement.
$vrai = 1; while(true) $vrai++;
Concernant ta class ça dépend de ce que tu attends.
Si dans le même script tu utilises 2 (ou +) objets PDO avec un code comme celui-ci
<?php
class MaClass{
	private $a = 0;
	// Les attributs de visibilité pour les méthodes
	// sont volontairement absents
	function __construct(){
	}
	function add($value){
		$this->a += $value;
	}
	function getValue(){
		return $this->a;
	}
}
$maClass = new MaClass();
$maClass->add(5);
echo $maClass->getValue() . '<br />';
$maClass2 = new MaClass();
$maClass2->add(3);
echo $maClass2->getValue() . '<br />';
?>
Tu obtiendras ce résultat
5
3
les "query" ne s'additionneront pas.
Par contre avec celui-ci
<?php
class MaClass{
	static $a = 0;
	// Les attributs de visibilité pour les méthodes
	// sont volontairement absents
	function __construct(){
	}
	function add($value){
		self::$a += $value;
	}
	function getValue(){
		return self::$a;
	}
}
$maClass = new MaClass();
$maClass->add(5);
echo $maClass->getValue() . '<br />';
$maClass2 = new MaClass();
$maClass2->add(3);
echo $maClass2->getValue() . '<br />';
?>
Tu obtiendras
5
8
Là, la première valeur est conservée.

Posté : 25 nov. 2006, 14:55
par jojolapine
Merci beaucoup pour ce complément d'information Ajoloca,
je vais tester tout de suite si ça fonctionne ou non...

Posté : 25 nov. 2006, 15:28
par jojolapine
Bon me revoilà après les tests...
pas très concluants :cry:
tout d'abord voici le code utilisé:
<?php
/**
 * Compteur de requêtes.
 *
 * Classe étendue de PDO destinée à compter le nombre de requêtes envoyées.
 */
class SQL extends PDO
{
    /**
     * initialisation d'une variable de comptage
     *
     * @var Int
     */
    static $nbrQuery = 0;

    /**
     * redéfinition des méthodes de PDO.
     * Chaque méthode utilisant une requête SQL incrémentera le compteur.
     * 
     * @todo faire de même avec les autres fonctions qui effectuent des requêtes.
     */
    
    /**
     * Redéfinition de la methode parent::query()
     */
    public function query($q)
    {
        parent::query($q);
        $this->nbrQuery++;
    }

    /**
     * Récupération du nombre de requêtes.
     *
     * @return Int
     */
    public function getnbrQuery()
    {
        /* je mettrai éventuellement une variable en option pour avoir 
           les différences en tre requête directe préparée. */
        return $this->nbrQuery;
    }
}
$user='XXX';
$pass='XXX';
$connec=new SQL('mysql:host=xxx;dbname=yyy', $user, $pass);
$sql='SELECT * FROM `matable`';
foreach ($connec->query($sql) as $row){
echo '<pre>';
print_r($row);
echo '</pre>';
}
echo 'Nombre de requêtes effectuées: '.$connec->getnbrQuery();
?>
bon et bien il y a une erreur, car je n'arrive pas à gérer correctement les paramètres de la fonction query...
ceci dit, dans la doc : http://fr2.php.net/manual/fr/function.pdo-query.php je ne comprend pas tout ce qui est écrit pour les paramètres, de plus, seul le premier paramètre statement est expliqué!
donc je sais pas trop si déja je m'en sort pas avec la méthode query, je viendrai à bout des autres?

Posté : 25 nov. 2006, 15:40
par Ajoloca
Re,

Je pense que tu doit avoir des messages d'erreur PHP
Tu accèdes à une variable de type statique donc, je ne suis pas sur que ça, ça passe
$this->nbrQuery++;
et ça non plus
return $this->nbrQuery;
Elle est où ta méthode constructeur ???

Posté : 25 nov. 2006, 15:45
par jojolapine
Bon le fait de faire ++ sur une variable static, je vais changer, mais je ne pense pas que ce soit ça, car je n'ai pas de message d'erreur la dessus, mon message d'erreur indique que l'argument apporté à foreach n'est pas correct, et je pense que ça vient du fait que j'ai mal défini les arguments de la méthode query...
pour ce qui est du constructeur, j'ai gardé celui de PDO, ça peut se faire non?

Posté : 25 nov. 2006, 15:52
par Ajoloca
Re,
Tu ne peux pas accèder à une propriété qui a un attribut "static" avec $this->propriété;
il faut utiliser self::$propriété

Regarde bien les deux code que je t'ai donné plus haut.

Posté : 25 nov. 2006, 15:59
par jojolapine
c'est bon j'ai changer le code pour les accès à la var static... seulement, mes arguments de la méthode query ne sont toujours pas bon... :cry:

Posté : 25 nov. 2006, 16:16
par Ajoloca
Re,
PQ ne testes tu pas le retour de
$connec=new SQL('mysql:host=xxx;dbname=yyy', $user, $pass);
ou mieu encore procède par étapes
Crée un constructeur qui appele le constructeur de PDO et tu testes son retour QQ chose du style (à vérifier)
<?php
class SQL extends PDO{
	public function __construct($dsn, $user, $pass){
   	try{
      	   parent::__construct($dsn, $user, $pass);
   	}catch(PDOException $e){
      	   throw $e;
   	}
   }
}
?>
Tu testes déjà la création de ta nouvelle class, quand ça sera au point tu passes à la phse suivante, ...

Posté : 25 nov. 2006, 16:46
par jojolapine
J'ai agit comme tu me l'as conseillé, il n'y a aucune erreur générée à la connection...
Je reste persuadé que cela vient des paramètres de la méthode query...
Je pense pas que j'arriverai à quelquechose... sauf si il y a un moyen de ne pas se préocuper des arguments (ce dont je doute)...
Sinon j'ai une autre méthode: :lol:
class compteur {
  static $nbr=0;
  function increment(){
    self::$nbr+=1;
  }
  function getnbr(){
    return self::$nbr;
  }
}

$connection=new PDO(...);
$compteur= new compteur;
$sql='...';
$connection->exec($sql);
$compteur->increment();
$sql2='...';
$connection->exec($sql2);
$compteur->increment();
echo 'Nombre de requête: '.$compteur->getnbr();

c'est une blague hein ... :)

Posté : 25 nov. 2006, 16:54
par Ajoloca
Re,

Comme je te l'ai expliqué plus haut
$cnx->query($sql)
et
$cnx->exec($sql)
c'est pas du tout la même chose.
Ne sachant pas ce que contient $sql
$sql='...';
je ne peux pas te dire

Posté : 25 nov. 2006, 17:04
par jojolapine
le second exemple, c'était pour de la blague, j'ai même pas essayé :wink: