Page 1 sur 1

class mysql - requete imbriqué

Posté : 28 oct. 2005, 13:05
par Vianney
Yop yop tout le monde,
voila je passe doucement a PHP5 orienté objet avec un classic : une classe MySQL.

J'ai un petit probleme pour imbriquer une requete dans une autre.

Voila le code de ma classe
<?php
class Mysql {
	
	/*
	*  $error: error report
	*/
	public $error;
	
	/*
	*  $host: the name or IP address of the MySQL server
	*/
	private $host;

	/*
	*  $login: login and your password to access to the MySQL server
	*  
	*/
	private $login;
	private $password;

	/*
	*  $DB: name of the database you need to connect to
	*/
	private $DB;

	/*
	*  $connect_id: connection identifiant
	*/
	private $connect_id;

	/*
	*  $result_id: query result identifiant
	*/
	private $result_id;

	/*
	*  __construct create a new MySQL object
	* eg: $DB = new Mysql();
	*/
	function __construct($aHost='***',$aLogin='***',$aPassword='***',$aDB='intranet') {
	  $this->host = $aHost;
	  $this->login = $aLogin;
	  $this->password = $aPassword;
	  $this->DB = $aDB;
	  $this->connect_id = false;
	  $this->error = false;
	}
	
	
	/*
	*  connect set the connection with the database
	*  eg: $DB->connect();
	*/
	function connect() {
	  $this->connect_id = mysql_connect($this->host,$this->login,$this->password);
	  if(!$this->connect_id) {
			$this->error = 'Can not connect to the database. Check connection information.';
			return false;
	  }
	  else {
			if(!mysql_select_db($this->DB,$this->connect_id)) {
				$this->error = 'You are not allow to access this database or the database "'.$this->DB .'" does not exist.';
				return false;
			}
			else {
				return $this->connect_id;
			}
	  }
	}
	
	/*
	*  send a query to the database. $query is a string variable
	*  eg: DB->sendQuery("SELECT name FROM clients_tbl");
	*/
	function sendQuery($query) {
	  if(!$this->connect_id) {
	    $this->error = 'You are not connected to a MySQL database.';
	    return false;
	  }
	  else if(!$this->result_id = mysql_query($query,$this->connect_id)) {
	    $this->error = mysql_error();
		return false;
	  }
	  else {
		return $result;
	  }
	}
	
	/*
	*  method to use a query previously done
	*  while ($data = $DB->fetchQuery()) 
	*  {
	*	echo $data['name'] ."<br />\n";
	*   }
	*/
	function fetchQuery() {
	  if(!$this->connect_id) {
	    $this->error = 'You are not connected to a MySQL database.'; 
	    return false;
	  }
	  else if(!$this->result_id) {
	    $this->error = 'You have to do a query to a database to get the number of row in a database.';
		return false;
	  }
	  else {
	    return mysql_fetch_assoc($this->result_id);
	  }
	}
	
	/*
	*  count the number of row of a query
	*  eg: $DB->numRow() 
	*/
	function numRow() {
	  if(!$this->connect_id) {
	    $this->error = 'You are not connected to a MySQL database.'; 
	    return false;
	  }
	  else if(!$this->result_id) {
	    $this->error = 'You have to do a query to a database to get the number of row in a database.';
		return false;
	  }
	  else {
	    return mysql_num_rows($this->result_id);
	  }
	}

	function prepareJumble($string) {
		$ready = addslashes($string);
		return $ready;
	}
	
	
	/*
	*  close the MySQL connection
	*  eg: $DB->close() 
	*/
	function close() {
      return mysql_close($this->connect_id) ;
    }
	
}
?>
Rien d'extraordinaire :)

dans ma page:
<?php
//1) J'inclue ma class
require("class.mysql.php");

//2 J'ai créé un objet mysql:
$benDb = new Mysql();

//3) Je me connect et fait ma requete de selection
if(!$benDb->connect()) {
   echo $benDb->error;
}
else {
   $benDb->sendQuery('SELECT id,name,firstname,department FROM people ORDER BY firstname'); //le champ department contient un identifiant dans cette table. 

//4) J'affiche les infos et c'est la que ca couille!
while($tablePeople = $benDb->fetchQuery())
{
   print '<tr><td width="250px" height="25px" align="left" id="list"> '.$tablePeople['firstname'].' '.$tablePeople['name'].' </td>'; //affiche le prenom et nom de la personne
   $benDb->sendQuery('SELECT department FROM people WHERE id='.$tablePeople['department'].''); //si je fait cette requete, avec laquelle je voulais faire la correspondance entre l'id (de type INT) et le nom du departement (de type STRING), ma variable $tablePeople = $benDb->fetchQuery() ne contient plus rien :/// et donc mon code n'affiche que le nom et prenom de la premiere personne. Si je la commente elle m'affiche bien tous les noms et prenoms dans la base. 
   $departmentName = $benDb->fetchQuery();
   print '<td width="200px" height="25px" align="left" id="list"> '.$departmentName['department'].' </td></tr>
				';
			}
?>
Ma question est comment faire pour plusieur requete imbriqué. Je pensais que le fait de mettre $benDb->fetchQuery() dans une variable $tablePeople me permettrais de la réutiliser apres mais apparement non.
Je seche... Quelqu'un a une idée ?

Merci d'avance.

ps: si vous avez des suggestions ou commentaire pour améliorer ma classe mysql n'ésitez pas

Posté : 28 oct. 2005, 13:25
par Truc
Salut, tu fait 2 "sendQuery" pour le meme objet donc tu perd le résulat de la 1ere requete lors du 2eme appel.

peut etre en créeant un 2nd objet Mysql:
$benDb2 = new Mysql(); 
puis de réutiliser cet identifiant pour la 2nd requete.

de plus dans la fonction "sendQuery()" d'ou sort le dernier return =>
return $result;

Autre chose, il me semble que lorsque tu as une fonction qui retourne un résultat tu dois l'affecter a quelque chose:
$r=$benDb->sendQuery(...);

Posté : 28 oct. 2005, 13:31
par jeff
salut
je comprend pas ton probeleme vu que tu n'utilise pas de requete preparer??
sinon j'ai creer aussi une class similaire base sur celle de Daoud
si ca peut te donné des idées(elle ne gere pas les requete inbriqué n'y les transaction)

mysqdb
<?php
class Mysqldb
{
	private $res;
	private $conn;
	
	public function __construct($serveur,$login,$pass,$db)
	{
		$this->conn=@mysql_connect($serveur,$login,$pass);
		if($this->conn==false)
		{
			throw new MyException('Connexion au serveur MySQL impossible-<br/>serveur : '.$serveur.'<br/>login : '.$login.'<br/>pass : '.$pass.'<br/>base : '.$db);
		}
		else
		{
			try{
				if(FALSE===mysql_select_db($db,$this->conn))
					throw new MyException('Base introuvable sur le serveur MySQL');
				}
			catch(MyException $e)
				{	
					$e->exceptionlog();
					//echo 'message'.$e->getMessage().'<br />';
					//echo 'code'.$e->getCode().'<br />';
				}

		}
	}
	
	
	public function execute($sql)
	{
		//echo $sql;
		try
		{
			if(FALSE===($this->res=mysql_query($sql,$this->conn)))
				throw new MyException($this->res.' n\'est pas un resultat valide<br />'.$sql);
		}
		catch(MyException $e)
			{//echo $e->getMessage();
			$e->exceptionlog();}
	}
	
	#retour une ligne sous forme de resultat
	public function rows()
	{
		try
		{
			if(mysql_num_rows($this->res)>0)
					 return	mysql_fetch_row($this->res);
			else
				throw new  MyException('pas de resultat trouver pour :'.$this->res);
		}
		catch(MyException $e)
			{//echo $e->getMessage();
			$e->exceptionlog();
			}
	}
	
	#retourne un nombre de ligne
	public function num_rows()
	{
		return mysql_num_rows($this->res);
	}
	
	#retourne un tableau numerique
	public function GetArray()
	{
		if(mysql_num_rows($this->res)>1)
		{
			while(false!=($rows=$this->rows()))
				$tableau[]=$rows;
		}
		else
			$tableau=$this->rows($this->res);
		return $tableau;
	}
	
	# requete ne fonctionnant pas
	public function GetArrayAssoc()
	{
		while($d=mysql_fetch_array($this->res))
		{
			$tab[]=$d;
		}
		return $tab;
	}
	
	#recupere le dernier id inserer
	public function last_id()
	{
		return mysql_insert_id($this->conn);
	}
	#retourne le nombre d'enregistrement afecté
	public function change_rows()
	{
		return mysql_affected_rows($this->conn);
	}
	
	
	public function __destruct()
	{
		mysql_close($this->conn);
	}
	/**
	*Methode de pour documentation
	*/
	
	 public static function GetInstance() {
        if (empty(self::$Instance)) {
            $class = __CLASS__;
            self::$Instance = new $class;
        }
        return self::$Instance;
    }
}
?>
classe sql
<?php
abstract class Sql
{
	protected $db;
	
	#requete select normal qui renvoi en tableau numerique
	public function Select($param=null,$chaine=null)
	{
		$req='SELECT '.join(",",$this->Achamp);
		$req.=' FROM '.join(",",$this->Atable);
		if($param!=null)
		{
			$req.=' WHERE ('.join(') AND (',$param).') ';
		}
		else
			$req.=' WHERE 1'; 	
		$req.=' ORDER BY '.$this->Achamp[0].' ASC ';
		if($chaine!=null)
			$req.=$chaine;
			//echo $req;
		$this->db->execute($req);
		return $this->db->GetArray();
	}
						
	#requete select qui renvoi true si $val existe false sinon
	
	public function SelectTrue($param=null,$chaine=null)
	{
		$req='SELECT '.join(",",$this->Achamp);
		$req.=' FROM '.join(",",$this->Atable);
		if($param!=null)
			$req.=' WHERE ('.join(') AND (',$param).') ';
		else
			$req.=' WHERE 1'; 
		if($chaine!=null)
			$req.=$chaine;
		$this->db->execute($req);
		$this->db->num_rows()===1?$flag=true:$flag=false;
		return $flag;
	}

	
	public function Insert_auto($valeur,$chaine=null)
	{
		$req='INSERT INTO '.$this->Atable;
		$erq.=' ('.join(",",$this->Achamp);
		$req.=' VALUES ('.join(",",$valeur).')';
		if($chaine!=null)
			$req.=$chaine;	
		$this->db->execute($req);
		return $this->db->last_id();
	}

	public function Update($valeur,$chaine=null)
	{
		$req='UPDATE '.join(",",$this->Atable);
		$req.=' SET'.join(",",$this->Achamp=$valeur);	
		if($chaine!=null)
			$req.=$chaine;
		$this->db->execute($req);
		return $this->db->change_rows();
	}

	public function delete($table,$param=null,$chaine='LIMIT 1')
	{
		$req='DELETE FROM '.$this->Atable;
		assert($param!=null);
		foreach($param as $cle => $val)
		{
			$cle==$row?$req.=$val:$req.=$val.' and ';
		}
		$req.=$chaine;
		$this->db->execute($req);
	}

	public function Grant($arr)
	{
		$req='GRANT '.join(",",$arr['actions']);
   		$req.=' ON '.join(",",$arr['base']);
    	$req.=' TO '.$arr['log'].'@'.$arr['serveur'];
        $req.='IDENTIFIED BY '.$arr['mdp'];
        $this->db->execute($req);
	}
	
}
?>
clasee dao
<?php
class DAO extends Sql
{	
	protected $db;
	protected $ArrayTable;
	protected $ArrayChamp;
	
	public function __construct($db)
	{
		$this->db=$db;//permet d'appeler les methodes de treitement des données
	}
	
	public function SetVar($ArrayTable,$ArrayChamp)
	{
		$this->Atable=$ArrayTable;
		$this->Achamp=$ArrayChamp;
	}

	public function __destruct()
	{
	}

}
?>

Posté : 28 oct. 2005, 13:35
par Vianney
Merci pour ton aide truc :)

Ouai oki je vais essayé de partir la dessus.

LoL putin t'as des yeux de lynx truc :D
else {
    return $result;
} 
corrigé pour
else {
   return $this->result_id;
}
Sinon pour le fait d'etre obligé d'affecter obligatoirement, me reférent a mes cours de c++ que j'aurais pas du sécher :/, il me semble que c'est si je souhaite utiliser le résultat que retourne la fonction mais si quelqu'un pouvait confirmer ca serait magnifique :)

Posté : 28 oct. 2005, 13:38
par Vianney
Euh j'ai peut etre fait un abus de langage en disant "requete imbriqué"... En fait, je parlais d'utiliser le résultat d'une requete dans une autre en fait jeff. Donc je sais pas si requete imbriqué a une autre signification?

edit - merci pour ta classe je vais regarder ca -

Posté : 28 oct. 2005, 13:41
par jeff
moi je pensais a ce genre de truc
select gnagna where id=(select gnagna)