affichage nombre de réponse sur mon forum

WRInaute occasionnel
Bonjour,
Je suis en train de faire un petit forum pour mon site internet et là je bloque sur un problème qui peut paraitre simple pour certains mais que je n'arrive pas à résoudre.
Sur la page d'accueil de mon forum je fais afficher tous les sujets du forum.
Je voudrai affichez le nombre de réponses qui ont été postées par les internautes à coté de chaque sujet.
Le problème vient de la partie du code ci-dessous ou j'affiche // on affiche le nombre de réponse de ce sujet
En fait au lieu de n'afficher que le nombre de reponses pour le sujet en question j'ai tout les nombres de reponses qui s'affiche a chaque fois.... mais pour faire simple rien ne vaut une image :
img-forumbis.gif


Je vous mets le code de ma page complète car par bout de code c pas évident.


mes tables du forum :
Code:
CREATE TABLE `forum_sujets` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `auteur` varchar(30) collate latin1_german2_ci NOT NULL,
  `titre` text collate latin1_german2_ci NOT NULL,
  `date_derniere_reponse` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY  (`id`)
);

CREATE TABLE `forum_reponses` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `auteur` varchar(30) collate latin1_german2_ci NOT NULL,
  `message` text collate latin1_german2_ci NOT NULL,
  `date_reponse` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `correspondance_sujet` int(6) NOT NULL,
  PRIMARY KEY  (`id`)
);

et le code de ma page d'accuel du forum :
Code:
<?php
function switchcolor()
 { 
   static $col;
   $couleur1 = "#F9D893";
   $couleur2 = "#F6C664";

    if ($col == $couleur1)
     {
       $col = $couleur2;
     }
    else
     {
       $col = $couleur1;
     }
    return $col; 
 }

$req = mysql_query("SELECT forum_sujets.id, forum_sujets.auteur, forum_sujets.titre, forum_sujets.date_derniere_reponse, forum_reponses.message, forum_reponses.correspondance_sujet FROM forum_sujets INNER JOIN forum_reponses ON (forum_reponses.correspondance_sujet = forum_sujets.id) group by forum_sujets.id order by forum_sujets.date_derniere_reponse desc,forum_reponses.date_reponse desc"); 

//$req = mysql_query("SELECT id, auteur, titre, date_derniere_reponse FROM forum_sujets ORDER BY date_derniere_reponse DESC"); 
// on compte le nombre de sujets du forum
$nb_sujets = mysql_num_rows ($req);
if ($nb_sujets == 0) {
        echo 'Aucun sujet';
}
else {
        echo '<h3>Nombre total de sujet postés sur le Forum :'.$nb_sujets.'</h3>';
        echo '<table width="780" border="0" cellpadding="5" cellspacing="0">
    <tr>
        <td>
        <span class="orange">Titre du sujet</span>
        </td>
        <td>
        <div align="center"><span class="orange">Auteur</span></div>
        </td>
                <td>
        <div align="center"><span class="orange">Vues</span></div>
        </td>        
                <td>
        <div align="center"><span class="orange">Réponses</span></div>
        </td>
        <td>
        <div align="center"><span class="orange">Date dernière réponse</span></div>
        </td>        
    </tr>';

        // on va scanner tous les tuples un par un
        while ($data = mysql_fetch_array($req)) {

        // on décompose la date
        sscanf($data['date_derniere_reponse'], "%4s-%2s-%2s %2s:%2s:%2s", $annee, $mois, $jour, $heure, $minute, $seconde);

        // on affiche les résultats
?>
    <?php echo "<tr bgcolor=\""; echo switchcolor(); echo "\">" ?>
    <?php $Id[]=$data['id']; ?>
<?php
        echo '<td>';
        // on affiche le titre du sujet, et sur ce sujet, on insère le lien qui nous permettra de lire les différentes réponses de ce sujet
        echo '<a href="./lire_sujet.php?id_sujet_a_lire=' , $data['id'] , '">' , $data['titre'] , '</a>';
        //aperçu du message de l'internaute
        echo '<p>'.substr($data['message'], 0, 80). '...</p>';

        echo '</td><td><div align="center">';
        // on affiche le nom de l'auteur de sujet
        echo $data['auteur'];
        echo '</div></td><td><div align="center">';

        // on affiche le nombre de fois ou le sujet a été vue
        echo 'vue';
        
        echo '</div></td><td><div align="center">';

 
        


// on affiche le nombre de réponse de ce sujet
      $sqlrep = 'SELECT *, COUNT(forum_reponses.id) AS num_reponses FROM forum_sujets LEFT JOIN forum_reponses ON forum_reponses.correspondance_sujet = forum_sujets.id GROUP BY forum_sujets.id ';
      $reqrep = mysql_query($sqlrep) or die('<u>Probleme SQL</u> : '.$sqlrep.'<br>'.mysql_error());
        
                while($resultnum = mysql_fetch_array($reqrep))   
                        {
                        $num_reponses = $resultnum['num_reponses'];
                        if ($num_reponses == 1) 
                                { 
                                echo '0 réponse';
                                }
                        elseif ($num_reponses == 2)
                                {
                                echo '1 réponse';
                                }
                        else 
                                {
                                $num_reponses = $num_reponses - 1;
                                echo $num_reponses.' réponses';
                                }
                        }







        
        echo '</div></td><td><div align="center">';

        // on affiche la date de la dernière réponse de ce sujet
        echo $jour , '-' , $mois , '-' , $annee , ' ' , $heure , ':' , $minute;
        }

        echo '</div></td></tr></table>';

}

// on libère l'espace mémoire alloué pour cette requête
mysql_free_result ($req);
// on ferme la connexion à la base de données.
mysql_close ();
?>
 
Nouveau WRInaute
Bonsoir,

j'ai un peu de mal à me rendre compte comme ça mais si tu rajoutais WHERE forum_sujets.id = $data['id'] ça marcherait pas?
 
WRInaute discret
exact tu ajoute un where pour affiner ta recherche :


$nombre_reponse = mysql_query("SELECT * FROM forum_reponses where correspondance_sujet= '$id' ");
$resultat_nombre_reponse = (mysql_num_rows($nombre_reponse ));

si correspondance_sujet correspond bien à l'id forum_sujets
 
WRInaute accro
tu te complique énormément la vie pour rien, il n'y a rien a ajouter mais surtout des trucs a enlever :
1/ tu fait plusieurs requêtes là ou une est suffisante
2/ tu complique le code pour rien.

j'ai vite fait créé tes tables en locl et injecté 4 messages sur deux sujets (un avec 3 et un avec un message) pour tester.

ta première requête est la suivante :

SELECT forum_sujets.id, forum_sujets.auteur, forum_sujets.titre, forum_sujets.date_derniere_reponse, forum_reponses.message, forum_reponses.correspondance_sujet FROM forum_sujets INNER JOIN forum_reponses ON (forum_reponses.correspondance_sujet = forum_sujets.id) group by forum_sujets.id order by forum_sujets.date_derniere_reponse desc,forum_reponses.date_reponse desc

elle renvoie chez moi un truc du genre :

Code:
id 	auteur 	titre 	date_derniere_reponse 	message 	correspondance_sujet
1 	toto 	test toto 	0000-00-00 00:00:00 	message à toto 	1
2 	titi 	test titi 	0000-00-00 00:00:00 	message de titi 	2

Si tu la complète avec la fonction count de ta seconde requête (qui soit dit en passant va être exécutée autant de fois qu'il y a de sujet (pas bon pour le rendement)) tu obtient :

SELECT forum_sujets.id, forum_sujets.auteur, forum_sujets.titre, forum_sujets.date_derniere_reponse, forum_reponses.message, forum_reponses.correspondance_sujet, COUNT(forum_reponses.id) AS num_reponses FROM forum_sujets INNER JOIN forum_reponses ON (forum_reponses.correspondance_sujet = forum_sujets.id) group by forum_sujets.id order by forum_sujets.date_derniere_reponse desc,forum_reponses.date_reponse desc
Code:
soit un recordset du genre :

id 	auteur 	titre 	date_derniere_reponse 	message 	correspondance_sujet 	num_reponses
1 	toto 	test toto 	0000-00-00 00:00:00 	message à toto 	1 	3
2 	titi 	test titi 	0000-00-00 00:00:00 	message de titi 	2 	1

qui comprend toutes les informations dont tu as besoins pour ton affichage.

Donc pour ton exemple qui comprend 4 sujets tu passe de 5 requêtes a 1 et tu n'a rien a faire en plus dans ta boucle d'affichage qui se simplifie d'autant:
en gros et approximativement ->
Code:
        echo '<h3>Nombre total de sujet postés sur le Forum :'.$nb_sujets.'</h3>';
        echo '<table width="780" border="0" cellpadding="5" cellspacing="0">
    <tr>
        <td>
        <span class="orange">Titre du sujet</span>
        </td>
        <td>
        <div align="center"><span class="orange">Auteur</span></div>
        </td>
                <td>
        <div align="center"><span class="orange">Vues</span></div>
        </td>       
                <td>
        <div align="center"><span class="orange">Réponses</span></div>
        </td>
        <td>
        <div align="center"><span class="orange">Date dernière réponse</span></div>
        </td>       
    </tr>';

        // on va scanner tous les tuples un par un
        while ($data = mysql_fetch_array($req)) {

        // on décompose la date
        sscanf($data['date_derniere_reponse'], "%4s-%2s-%2s %2s:%2s:%2s", $annee, $mois, $jour, $heure, $minute, $seconde);

        // on affiche les résultats
?>
    <?php echo "<tr bgcolor=\""; echo switchcolor(); echo "\">" ?>
    <?php $Id[]=$data['id']; ?>
<?php
        echo '<td>';
        // on affiche le titre du sujet, et sur ce sujet, on insère le lien qui nous permettra de lire les différentes réponses de ce sujet
        echo '<a href="./lire_sujet.php?id_sujet_a_lire=' , $data['id'] , '">' , $data['titre'] , '</a>';
        //aperçu du message de l'internaute
        echo '<p>'.substr($data['message'], 0, 80). '...</p>';

        echo '</td><td><div align="center">';
        // on affiche le nom de l'auteur de sujet
        echo $data['auteur'];
        echo '</div></td><td><div align="center">';

        // on affiche le nombre de fois ou le sujet a été vue
        echo 'vue';
       
        echo '</div></td><td><div align="center">'.$data['num_reponses'].' réponses';

        echo '</div></td><td><div align="center">';

        // on affiche la date de la dernière réponse de ce sujet
        echo $jour , '-' , $mois , '-' , $annee , ' ' , $heure , ':' , $minute;
        }

        echo '</div></td></tr></table>';

...
 
WRInaute occasionnel
Bonjour,
j'ai opté pour la solution de Zeb qui fonctionne très bien et qui effectivement allege bien le code.
par contre zeb tu dis :
Si tu la complète avec la fonction count de ta seconde requête (qui soit dit en passant va être exécutée autant de fois qu'il y a de sujet (pas bon pour le rendement)) tu obtient...
Si je comprend bien, la fonction count n'est donc pas la bonne méthode pour faire ceci. Mais comment faire autrement ?
 
WRInaute accro
en fait j'ai peut être mal formulé ma pensée:

count() est adaptée a ce que tu cherche a faire (a vrai dire je pense même pas que tu ai un autre choix), mais ce qui me semble inadapté est de faire une requête a chaque sujet pour compter le nombre de réponse.

j'ai eu , il y a pas très longtemps, a modifier tout un tas de requête sur un site pour alléger le serveur je suis passé de pages faisant 200 requêtes une fois en charge, a des pages n'en faisant qu'une dizaine donc je suis très 'au fait' des requêtes dans les boucles qui sont des sources dévastatrices de ressource serveur.

Si tu prend l'index d'un forum un peut fréquenté, avec ton script de départ, tu aurais vite fait de mettre la machine a genoux avec un peut de trafic sur le site.
 
WRInaute occasionnel
ok ok merci pour ces explications.
par contre j'ai un autre petit soucis mais cette fois au niveau de l'affichage de l'auteur de la dernière réponse.
dans la partie ou j'affiche la date de la dernière réponse je voudrai affiché juste en dessous l'auteur de cette dernière réponse.
Code:
// on affiche la date de la dernière réponse de ce sujet
echo $jour , '-' , $mois , '-' , $annee , ' ' , $heure , ':' , $minute;
echo '<br/>par '.$data['auteur'];

le hic en faisant ça c'est que je récupère le nom de l'auteur du sujet et pas celui de la dernière réponse.
Comment faire la distinction entre les 2 et afficher le bon nom ?
img-forum-auteur.gif
 
Discussions similaires
Haut