Class dans une boucle

ViPHP
ViPHP | 4674 Messages

07 mai 2009, 15:21

Voir le message de pascaltje :-).
« 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:31

Ok je vois , c'est alors au niveau MYSQL que je vais avoir besoin d'aide.

Car en fait , ca se présente comme ça :

J'ai une table nommée PUB

Code : Tout sélectionner

CREATE TABLE `pub` ( `pub_id` int(11) NOT NULL auto_increment, `pub_fk_user_id` int(11) NOT NULL, `pub_title` varchar(40) NOT NULL, `pub_txt` text, `pub_fk_type_id` int(11) NOT NULL, `pub_start` datetime NOT NULL, `pub_end` datetime NOT NULL, PRIMARY KEY (`pub_id`) )

et une autre nommée PUB_VISITE

Code : Tout sélectionner

CREATE TABLE `pub_visite` ( `pub_visite_fk_pub` int(11) NOT NULL, `pub_visite_fk_user` int(11) default NULL, `pub_visite_date` datetime NOT NULL, `pub_visite_ip` varchar(20) NOT NULL )
Donc en fait dans le tableau que je veux afficher avec ma boucle citée précédemment, je souhaite récupérer le nombre de visite pour cette pub.

Voilà ce que ça donne actuellement:
$sql->qrySQL("SELECT * FROM pub WHERE pub_fk_user_id = '".$_SESSION['user']['id']."' ORDER BY ".$orderby." ".$_POST['sens']."");
		$nb = $sql->numRow();
		if($nb > 0)
			{
			
			echo "<table id=\"pub_list\" class=\"sortable\" cellspacing=\"0\" cellpadding=\"3\">";
			echo "<thead>";
			echo "<tr>";
				echo "<th id=\"pub_title\">";
				echo "<div align=\"left\">"._DENOMINATION_PUB_."</div>";	
				echo "</th>";
				echo "<th id=\"pub_type\">";
				echo "<div align=\"center\">"._TYPE_."</div>";	
				echo "</th>";
				echo "<th id=\"pub_start\">";
				echo "<div align=\"center\">"._AJOUTE_."</div>";	
				echo "</th>";
				echo "<th id=\"pub_end\">";
				echo "<div align=\"center\">"._EXPIRE_."</div>";	
				echo "</th>";
				echo "<th class=\"nosort\">";
				echo "<div align=\"center\">"._VISITES_."</div>";	
				echo "</th>";
				echo "<th class=\"nosort\">";
				echo "<div align=\"center\">"._MODIFIER_."</div>";
				echo "</th>";
			echo "</tr>";
			echo "</thead>";
			if($nb > 10)
				{
				echo "<tfoot>";
					echo "<tr>";
					echo "<td>";
					echo "<div align=\"left\">"._DENOMINATION_PUB_."</div>";	
					echo "</td>";
					echo "<td>";
					echo "<div align=\"left\">"._TYPE_."</div>";	
					echo "</td>";
					echo "<td>";
					echo "<div align=\"left\">"._AJOUTE_."</div>";	
					echo "</td>";
					echo "<td>";
					echo "<div align=\"left\">"._EXPIRE_."</div>";	
					echo "</td>";
					echo "<td>";
					echo "<div align=\"left\">"._VISITES_."</div>";	
					echo "</td>";
					echo "<td>";
					echo "<div align=\"center\">"._MODIFIER_."</div>";
					echo "</td>";
				echo "</tr>";
				echo "</tfoot>";
				}
			echo "<tbody>";
			for($i=0;$i<$nb;$i++)
				{
				$data = $sql->fetchAssoc();
				echo "<tr>";
				echo "<td>";
				echo "<div align=\"left\" class=\"txt_container\"><b>".stripslashes($data['pub_title'])."</b></div>";
				echo "</td>";
				$sql2 = new SQLclass($db_name,$db_host,$db_user,$db_pass);
				$sql2->qrySQL("SELECT * FROM pub_type_lang WHERE pub_type_lang_fk_type_id = '".$data['pub_fk_type_id']."' AND pub_type_lang_fk_languages_id = '".$lang_id."'");
				$data2 = $sql2->fetchAssoc();
				echo "<td>";
				echo "<div align=\"center\" class=\"txt_container\">".stripslashes($data2['pub_type_lang_nom'])."</div>";
				echo "</td>";
				echo "<td>";
				echo "<div align=\"center\" class=\"txt_container\">".formatDate($data['pub_start'],'d-m-Y')."</div>";
				echo "</td>";
				echo "<td>";
				$expire = (checkExpireDate($data['pub_end']) == true)? 1 : 0;
				$class = ($expire == 1)? "expiredate" : "";
				echo "<div align=\"center\" class=\"txt_container\"><span class=\"".$class."\">".formatDate($data['pub_end'],'d-m-Y')."</span></div>";
				echo "</td>";
				echo "<td>";
				$sql2 = new SQLclass($db_name,$db_host,$db_user,$db_pass);
				$sql2->qrySQL("SELECT COUNT(*) AS nb_visites FROM pub_visite WHERE pub_visite_fk_pub = '".$data['pub_id']."' ");
				$nb_visite = $sql2->fetchResult('pub_visite');
				echo "<div align=\"center\" class=\"txt_container\">".$nb_visite."</div>";
				echo "</td>";
				echo "<td>";
				echo "<div align=\"center\" class=\"txt_container\"><a href=\"#\" onclick=\"gestUser('mod_pub','".$data['pub_id']."')\"><img src=\"images/ico_edit.png\" border=\"0\"/></a></div>";
				echo "</td>";
				
				echo "</tr>";
				}
			echo "</tbody>";
			echo "</table>";
Évidement je parviens à la faire sans problème avec ma deuxieme requête , je suis juste là pour essayer d'optimiser ce genre de requête.

Merci à vous

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

07 mai 2009, 16:30

Le problème avec ta classe (et c'est ce qui ne permet pas ce que tu veux faire) est qu'elle ne peut utiliser qu'une requête à la fois. C'est à dire qu'on est obligé d'instancier plusieurs objets de ta classe pour exécuter plusieurs requêtes dépendantes comme c'est le cas de ta boucle.

Il y a 2 solutions, soit tu suis les remarques qui te sont déjà faites comme : cette classe ne sert pas à grand chose car on peut s'en passer et utiliser simplement les fonctions mysql à la place et aussi la remarque sur le fait que tu peux exécuter une requête qui implique plusieurs tables mise en relation pour éviter de faire des boucles relationnelle en PHP.

Ou alors la deuxième solution consiste à encore retravailler ta classe pour permettre l'utilisation de plusieurs requêtes dans la même classe et voir même plusieurs connexions (pool de connexions) et ça c'est possible, il suffit donc de séparer l'objet connexion des objets requêtes avec liaison bien sur.

Voici un exemple:
<?php
class Connection {

    var $db_name ;
    var $db_host ;
    var $db_user ;
    var $db_pass ;
    var $ressource;
	
    //Implémenter la class
    function Connection($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 ;
		$this->open();
        }

    //Connection à la base de donnée
	function open()
        {
        	$connect = mysql_connect($this->db_host,$this->db_user,$this->db_pass);
        	if($connect){
				$db_select = mysql_select_db($this->db_name,$connect);
				if ($db_select)
            	{
            	$this->ressource = $connect;
				return true;
            	}
			}
        	return false;
        }
     // Ferméture de connexion
     function close()
        {
            if ($this->ressource != null) mysql_close($this->ressource);
         }
}

class Query
{
    var $connection;
    var $sql;
    var $recordset ;

    // Initialiser la classe

    function Query($connection, $sql=null)
      {
         if ($connection != null && get_class($connection) == "Connection" && $connection->ressource != null)
           {
              $this->connection = $connection->ressource;
              if ($sql != null)  $this->execute($sql); 
            }
       }
         
    // Exécuter SQL

    function execute($sql)
        {
        $this->sql = $sql;
        if ($this->connection != null)
           {
               $this->recordset = mysql_query($this->sql, $this->connection);
			   return true;
            }
         else return false;
        }
        
    // Assoc
    
    function fetchAssoc()
        {
           if ($this->recordset != null) return mysql_fetch_assoc($this->recordset );
           else return null;
        }
                
    //Num
    
    function numRow()
        {
        if ($this->recordset != null) return mysql_num_rows($this->recordset );
        else return null;  
        }
        
    function insertID()
        {
          if ($this->connection != null) return mysql_insert_id();
         else return null;
        }   
}

// programme de test
$con1 = new Connection("test","localhost","root","");
//
$query1 = new Query($con1, "SELECT * FROM personnel");
while ($data1 = $query1->fetchAssoc())
{
	$query2 = new Query($con1,"SELECT * FROM personnel WHERE titre = '".$data1['TITRE']."' AND nom <> '".$data1['NOM']."'");
	echo "<p>Le titre de la personne : " ,$data1['NOM'], " est " ,$data1['TITRE'],", il se trouve ", $query2->numRow()+1, " fois.</p>"; 
	if ($query2->numRow() >0){
	echo "<p>Les personne ayant le même titre sont: <ul>";
		while($data2 = $query2->fetchAssoc())
		{
			echo "<li>", $data2['NOM'],"</li>";
		}
		echo "</ul></p>";
	}
}
//
$con1->close();
?>
Voici les données de ce test:

Code : Tout sélectionner

-- -- Base de données: `test` -- -- -------------------------------------------------------- -- -- Structure de la table `personnel` -- -- Création: Jeu 02 Avril 2009 à 16:12 -- Dernière modification: Jeu 02 Avril 2009 à 16:15 -- CREATE TABLE IF NOT EXISTS `personnel` ( `NAS` int(11) NOT NULL, `NOM` varchar(30) NOT NULL, `PRENOM` varchar(30) NOT NULL, `SEXE` varchar(1) NOT NULL, `TITRE` varchar(100) NOT NULL, `SALAIRE` float NOT NULL, `CATEGORIE` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -- -- Contenu de la table `personnel` -- INSERT INTO `personnel` (`NAS`, `NOM`, `PRENOM`, `SEXE`, `TITRE`, `SALAIRE`, `CATEGORIE`) VALUES (555, 'Thibault', 'Yvon', 'M', 'Administrateur', 27000, 3), (222, 'Dupuis', 'Josée', 'F', 'Vendeur', 22500, 2), (666, 'Smith', 'Alex', 'M', 'Vendeur', 18000, 1);
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

D4Y
Eléphant du PHP | 52 Messages

07 mai 2009, 20:40

Merci pour cette solution qui me parait la mieux adaptée à ce que je veux faire.

Comme vous l'avez sans doute remarqué je ne suis nulle part dans les class PHP.

Mais les class que tu viens de me donner (connection et qry)ne serait-ce pas possible de faire un class Query extends Connection afin de ne pas devoir définir par exemple $con1 dans la ligne $query1 = new Query($con1, "SELECT * FROM personnel");

Cette question est p-e idiote mais c'est histoire de comprendre un peu mieux cette logique des class.

Merci beaucoup en tout cas pour cette aide déjà apportée.

PS:

J'ai trouvé cette class sur le net qu'ne pensez vous ?
J'avoue avoir du mal à tout comprendre.
/* 
Auteur : Bruno Sabot
Version : 1.1
Documentation : http://www.brunosabot.com/sqlclassphp.html

Changelog :
    v1.1 :
    - Ajout de la fonction QueryToArray()
    - Ajout de la fonction GetLastId()
*/

class Sql {
    private $host;
    private $user;
    private $pass;
    private $database;
    private $db;
    private $connect;
    private $nbquery = 0;
    private $query;
    private $sqlerr;
    private $result;
    private $throw=array(0=>'La fonction n\'existe pas',1=>'Impossible de se connecter à la base de données',2=>'Impossible de sélectionner une base de données',3=>'Connexion à la base de données est fermée',4=>'La reqûete est vide',5=>'Erreur MySQL',6=>'Aucune table à optimiser');

    public function __construct($host,$user,$pass,$db) {
        $this->host = $host;
        $this->user = $user;
        $this->pass = $pass;
        $this->database = $db;
        $this->Connect();
    }
    public function __destruct() {
        return true;
    }
    public function __call($m=NULL,$a=NULL) {
        echo 'Liste des fonctions de l\'objet SQL: Close, Query, Optimize, SetDatabase, SetHost, SetUser, SetPass, GetLastQuery, GetNbReq, GetResult, GetTables, GetHost, GetUser, GetDatabase';
        throw new Exception ($this->throw[0],0);
    }
    public function __sleep() {
        return true;
    }
    public function __wakeup() {
        $this->Connect();
    }
    public function __toString() {
        return 'Connecté à '.$this->database.', '.$this->nbquery.' reqûetes effectuées';
    }
    private function Connect() {
        $this->connect = @mysql_connect($this->host,$this->user,$this->pass);
        if ($this->connect === false) {
            throw new Exception($this->throw[1],1);
        }
        $this->SelectDB();
    }
    private function SelectDB() {
        $this->db = @mysql_select_db($this->database);
        if ($this->db === false) {
            $this->connect = false;
            throw new Exception($this->throw[2],2);
        }
        return $this->connect;
    }
    public function Close() {
        if ($this->connect === false) {
            @mysql_close($this->connect);
            $this->connect = false;
            $this->db = false;
            throw new Exception($this->throw[3],3);
        } 
        return true;
    }
    public function Query($query,$fa=false) {
        $this->query = $query;
        if ($this->connect === false) {
            throw new Exception($this->throw[3],3);
        }
        if (empty($this->query)) {
            throw new Exception($this->throw[4],4);
        }
        $this->result = mysql_query($this->query,$this->connect);
        $this->nbquery++;
        if ($this->result === false) {
            throw new Exception($this->throw[5].' : '.mysql_error(),5);
        }
        if ($fa===true) {
            $this->result = mysql_fetch_array($this->result);
            if ($this->result === false) {
                throw new Exception($this->throw[5].' : '.mysql_error(),5);
            }
        }
        return $this->result;
    }
    // Version 1.1
    public function QueryToArray($query,$fetcharray=false) {
        $d = array();
        $q = $this->Query($query);
        if ($fetcharray) {
            while ($r = mysql_fetch_array($q)) {
                $d[] = $r;
            }
        } else {
            while ($r = mysql_fetch_assoc($q)) {
                $d[] = $r;
            }
        }
        return $d;
    }
    // Version 1.1
    public function GetLastId() {
        return mysql_insert_id($this->connect);
    }
    public function Optimize() {
        $t = $this->GetTables();
        $c = count($t);
        if ($c==0) {
            throw new Exception($this->throw[6],6);
        }
        $r = 'OPTIMIZE TABLE ';
        for($i=0;$i<($c-1);$i++) {
            $r .= '`'.$t[$i].'`,';
        }
        $r.='`'.$t[$i].'`';
        return $this->Query($r);
    }
    public function SetDatabase($db) {
        if ($this->connect !== false) {
            $this->SelectDB();
        } else {
            throw new Exception($this->throw[3],3);
        }
        return true;
    }
    public function SetHost($host='localhost') {
        $this->Close();
        $this->host = $host;
        $this->Connect();
    }
    public function SetUser($user='root') {
        $this->Close();
        $this->user = $user;
        $this->Connect();
    }
    public function SetPass($pass='') {
        $this->Close();
        $this->pass = $pass;
        $this->Connect();
    }
    public function GetSave($s=false) {
        $a = $this->GetTables();
        $t = '';
        foreach ($a as $b) {
            $t .= '--<br />-- Structure de la table `'.$b.'`<br />--<br /><br />';
            $r = $this->Query('SHOW CREATE TABLE '.$b,true);
            $t .= $r[1].';<br /><br />--<br />-- Contenu de la table `'.$b.'`<br />-- <br /><br />';
            $nb = mysql_num_rows($this->Query('SHOW COLUMNS FROM '.$b));
            $qn = $this->Query('SELECT * FROM '.$b);
            while ($qv = mysql_fetch_array($qn)) { 
                $t .= 'INSERT INTO '.$b.' VALUES ('; 
                $i = 0; 
                while ($i < $nb) { 
                    $qv[$i] = str_replace("'","''",$qv[$i]);
                    $t .= "'".$qv[$i]."',"; 
                    $i++; 
                } 
                $t = substr($t,0,-1);
                $t .= ');<br />'; 
            }
        }
        if ($s) {
            $t = str_replace("<br />" , "\n",$t);
        }
        return $t;
    }
    public function GetLastQuery() {
        return $this->query;
    }
    public function GetNbReq() {
        return $this->nbquery;
    }
    public function GetResult() {
        return $this->result;
    }
    public function GetTables() {
        if (!($t = $this->Query('SHOW TABLES'))) {
            return $t;
        }
        while($u = mysql_fetch_array($t)) {
            $a[] = $u[0];
        }
        return $a;
    }
    public function GetHost() {
        return $host;
    }
    public function GetUser() {
        return $user;
    }
    public function GetDatabase() {
        return $database;
    }
    public function GetFunctions() {
        try { $this->__call(); } catch(Exception $e) {}
    }
}

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

07 mai 2009, 22:54

En fait, les classes que je t'ai présenté reprennent ta solution. Mais je pencherai plus pour la dernière classe que t'a pioché du Net, elle est plus complète.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène