Class dans une boucle

D4Y
Eléphant du PHP | 52 Messages

05 mai 2009, 13:38

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

Eléphant du PHP | 70 Messages

05 mai 2009, 13:41

Peut-tu me montrer le code de qrySQL? Merci

D4Y
Eléphant du PHP | 52 Messages

05 mai 2009, 13:45

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();
		}
	
	
}

Eléphant du PHP | 70 Messages

05 mai 2009, 13:53

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.

D4Y
Eléphant du PHP | 52 Messages

05 mai 2009, 13:56

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 ?

Eléphant du PHP | 70 Messages

05 mai 2009, 14:00

$this->qry tu le définis où?

D4Y
Eléphant du PHP | 52 Messages

05 mai 2009, 14:02

Dans la fonction

function qrySQL($SQLstr)
{
$connect = $this->connectDB();
$qry = mysql_query($SQLstr);
$this->qry = $qry ;
return $this->qry ;
}

Eléphant du PHP | 70 Messages

05 mai 2009, 14:03

$nb_result = $sql->numRow(); 
Ca fonctionne?

D4Y
Eléphant du PHP | 52 Messages

05 mai 2009, 14:10

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 ...")

Mammouth du PHP | 1029 Messages

06 mai 2009, 08:56

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 ;)
L'expérience est la somme de toutes nos erreurs.

ViPHP
ViPHP | 1024 Messages

06 mai 2009, 09:39

Et pourquoi tu n'utilises pas une jointure sur l'id ?

ça éviterait de faire 36 requêtes dans la boucle.

A+

Pascal

ViPHP
ViPHP | 4674 Messages

07 mai 2009, 10:49

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.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

D4Y
Eléphant du PHP | 52 Messages

07 mai 2009, 14:42

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 ")";

}

ViPHP
ViPHP | 4674 Messages

07 mai 2009, 14:59

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.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

D4Y
Eléphant du PHP | 52 Messages

07 mai 2009, 15:05

Merci mais que veux-tu dire par une meilleure requete SQL ?