Page 1 sur 2
Class dans une boucle
Posté : 05 mai 2009, 13:38
par D4Y
Bonjour,
J'utilise une class pour mes requêtes SQL.
Jusque là je m'en suis toujours sortis mais j'essaye un peu d'optimiser ma méthode.
Le problème que je rencontre est lorsque j'utilise ma class dans une boucle.
ex:
$sql = new SQLclass($db_name,$db_host,$db_user,$db_pass);
$sql->qrySQL("SELECT * FROM table");
$nb_result = $sql->numRow();
for($i=0;$i<$nb_result;$i++)
{
$data = $sql->fetchAssoc();
//Ce que je fais pour le moment et que je voudrais éviter
$sql2 = new SQLclass($db_name,$db_host,$db_user,$db_pass);
$sql2-> qrySQL("SELECT * FROM table2 WHERE table2_id = '".$data['table_id']."'");
$nb_result2 = $sql2->numRow();
}
Voilà donc je voudrais un astuce (je ne connais pas bien le fonctionnement des class) pour éviter de redéfinir ma classe (p-e un extend ??)
Merci d'avance
Posté : 05 mai 2009, 13:41
par Sodams
Peut-tu me montrer le code de qrySQL? Merci
Posté : 05 mai 2009, 13:45
par D4Y
Voici la class
class SQLclass {
var $db_name ;
var $db_host ;
var $db_user ;
var $db_pass ;
//Implémenter la class
function SQLclass($db_name,$db_host,$db_user,$db_pass)
{
$this->db_name = $db_name ;
$this->db_host = $db_host ;
$this->db_user = $db_user ;
$this->db_pass = $db_pass ;
}
//Connection à la base de donnée
function connectDB()
{
$connect = mysql_connect($this->db_host,$this->db_user,$this->db_pass);
$db_select = mysql_select_db($this->db_name,$connect);
if($connect && $db_select)
{
return true;
}
else{
return false;
}
}
// Requête SQL
function qrySQL($SQLstr)
{
$connect = $this->connectDB();
$qry = mysql_query($SQLstr);
$this->qry = $qry ;
return $this->qry ;
}
// Assoc
function fetchAssoc()
{
$result = mysql_fetch_assoc($this->qry);
$this->result = $result;
return $this->result;
}
// result
function fetchResult($data)
{
$result = mysql_result($this->qry,$data);
$this->result = $result;
return $this->result;
}
//Num
function numRow()
{
$nb = mysql_num_rows($this->qry);
$this->nb = $nb;
return $this->nb;
}
function insertID()
{
$id = mysql_insert_id();
$this->id = $id;
return $this->id;
}
function closeSQL()
{
mysql_close();
}
}
Posté : 05 mai 2009, 13:53
par Sodams
Je ne vois pas trop l'interet de ta classe.
Tu utilises juste les fonctions mysql, mises à part pour la connexion ou la tu effectues des tests.
Celà reviens exactement au même de mettre ta connexion dans un fichier include.
Tu n'auras plus après qu'a utiliser les mysql_fetch_array(par exemple) pour traiter tes requêtes puisque ta connexion sera initialisée sur chaque page, et la connexion ne situera quand même qu'a un seule endroit pour tous le site (je suppose que c'est ton but).
A moins que tu y vois d'autres avantages (ou que tu comptes l'utiliser autrement), je te déconseille d'utiliser cette classe (ou alors l'améliorer).
Pour ton problème, essaye peut-être de créer deux classes, connection et command.
Posté : 05 mai 2009, 13:56
par D4Y
Merci pour ta réponse mais y a t'il un moyen de ne pas devoir redéfinir dans la boucle ? et de continuer la avec la class déjà instanciée ? p-e ajouter une variable supplémentaire ?
Posté : 05 mai 2009, 14:00
par Sodams
$this->qry tu le définis où?
Posté : 05 mai 2009, 14:02
par D4Y
Dans la fonction
function qrySQL($SQLstr)
{
$connect = $this->connectDB();
$qry = mysql_query($SQLstr);
$this->qry = $qry ;
return $this->qry ;
}
Posté : 05 mai 2009, 14:03
par Sodams
$nb_result = $sql->numRow();
Ca fonctionne?
Posté : 05 mai 2009, 14:10
par D4Y
oui bien sur ma class fonctionne très bien.
Le seul soucis est que je dois faire $sql2->SQLclass($db_name,$db_host,$db_user,$db_pass);
dans une boucle pour pouvoir faire une 2ième qry $sql2->qrySQL("SELECT ...")
Posté : 06 mai 2009, 08:56
par Maitrepylos
Bonjour, dans ta boucle, tu refais plusieurs fois le même query
$data = $sql->fetchAssoc();
Cela n'est pas nécessaire au vu de ta classe, tu peux donc la sortir de ta boucle, libérant ainsi le string de ton select, pour un autre select ave le même objet (j'espère que tu suis).
donc ceci devrais rencontrer ta demande
$sql = new SQLclass($db_name,$db_host,$db_user,$db_pass);
$sql->qrySQL("SELECT * FROM table");
$nb_result = $sql->numRow();
$data = $sql->fetchAssoc();
for($i=0;$i<$nb_result;$i++)
{
$sql-> qrySQL("SELECT * FROM table2 WHERE table2_id = '".$data['table_id']."'");
$nb_result2 = $sql->numRow();
}
Je ferais 2 remarques, dans ta boucle, tu mets le résultat dans la variable $nb_result2, celle-ci n'est pas un tableau, donc seul le résultat de ta dernière itérations sera retenu, peut-être devrais tu faire ceci
$nb_result2[] = $sql->numRow();
2ième remarque, ta classe est une classe pour PHP4, faudrais la mettre à jours vers PHP5

Posté : 06 mai 2009, 09:39
par pascaltje
Et pourquoi tu n'utilises pas une jointure sur l'id ?
ça éviterait de faire 36 requêtes dans la boucle.
A+
Pascal
Posté : 07 mai 2009, 10:49
par Hywan
Hey

,
pascaltje++;
Utilise déjà un singleton pour gérer la connexion à la base de donnée.
Ensuite, évite les allers et retours entre MySQL et PHP (requête, traitements, requête, traitements) … Tout ce qui peut être fait du côté MySQL doit être fait car une grosse requête MySQL reste plus rapide que plusieurs petites avec aller et retours (symboliquement : un aller prend 1 unité de temps — donc 2 unités pour un aller et un retour —, alors que le traitement d'une grosse requête doit en prendre 0.2).
Et en plus, si tu utilises un singleton et que tu stockes ton instance dans une variable, pas besoin d'instancier 50 fois ton objet. En effet, il suffit de ré-appeler la méthode
qrySQL et c'est tout bon.
Posté : 07 mai 2009, 14:42
par D4Y
A vrai dire , j'ai pas trop compris l'explication de Maitrepylos car il me fait sortir mon fetchAssoc() de la boucle ... je aurais donc toujours le même résultat pour chaque élément de la boucle.
Le but étant de faire ce genre :
$sql = new SQLclass($db_name,$db_host,$db_user,$db_pass);
$sql->qrySQL("SELECT * FROM table");
$nb_result = $sql->numRow();
for($i=0;$i<$nb_result;$i++)
{
$data = $sql->fetchAssoc();
echo $data2['table_name'];
echo "(";
$sql-> qrySQL("SELECT * FROM table2 WHERE table2_id = '".$data['table_id']."'");
$nb_result2 = $sql->numRow();
for($j=0;$j<$nb_result2;$j++)
{
$data2 = $sql->fetchAssoc();
echo " ".$data2['table2_name'];
}
echo ")";
}
Posté : 07 mai 2009, 14:59
par Hywan
C'est un détail qui est négligeable d'après moi.
Concentre toi sur une meilleure requête SQL, ce sera l'amélioration la plus significative de ton code et les autres optimisations en découleront naturellement.
Posté : 07 mai 2009, 15:05
par D4Y
Merci mais que veux-tu dire par une meilleure requete SQL ?