Forum Clubic

(Multi)Réponse(s) à un commentaire

Salut à tous,

En exemple rapide j’ai une table de ce type :


comments(id, ref_id, user, commentaire,rep_id)

J’aimerai que l’on puisse répondre à un commentaire en particulier, qui sera mis en retrait en dessous du commentaire concerné, ça j’arrive à faire, et ça marche bien.

Code exemple:


while(){
comment
while(){
rep_comment
}
}

Je fais un while a chaque fois que je veux chercher une réponse à un commentaire déja posté, et vu que je ne fais que 2 while, disons que la personne B qui a répondu au commentaire de A, aprés A ne pourra pas répondre au commentaire de B, mais doit se répondre à lui même… ça créera une certaine confusion…

Donc, je me demandais s’il n’y avait pas une fonction ou une meilleure méthode que la mienne pour faire ça…avec ma manière si je souhaite aller plus loin, ça va être un peu lourd pour le serveur j’imagine, des boucles while pour chaque commentaire, avec d’autres calculs à l’intérieur… ça tiendra pas longtemps >_<

Si vous avez un lien, ou un tuto expliquant mieux celà, je suis preneur, j’ai cherché un peu sur le net… mais je trouve pas ce que je veux.

Merci

Ce que tu cherches s’appelle la récursivité, et les performances sont couci couça. En gros :


SELECT id AS "comment_id", 
                ref_id "parent_id",
                user AS "user_name",
                commentaire AS "comment"
FROM comments C

Suppose que tu exécutes cette requête, que id est l’identifiant de tes commentaires, que tu fais une restriction sur mettons l’identifiant d’une news, d’un topic, etc, que ref_id est l’identifiant du commentaire parent, alors tu aurais ça :

function display_all_comments($news_id, $parent = null) {
  $sql = sprintf('SELECT id AS "comment_id", 
                has_children,
                ref_id "parent_id",
                user AS "user_name",
                commentaire AS "comment"
FROM comments C 
WHERE C.news_id = %d', $news_id);
  if ($parent === null) {
    $sql .= ' AND C.ref_id IS NULL';
  } else {
    $sql .= sprintf(' AND C.ref_id = %d', $comment); // pas forcément utile, si donné uniquement que par la fonction
  }
  if (false === ($q = mysql_query($sql))) {
    echo 'erreur';
  } else while ($a = mysql_fetch_array($q)) {
    display_comment($a);
    if ($a['has_children']) {
      display_all_comments($news_id, $a['comment_id']);  
    }
  }
}

display_all_comments(xxx);

C’est l’algorithme de base. Les performances sont celles de la récursivité (donc éviter trop trop de profondeur, la pile n’aime pas :))

Maintenant, tu as d’autres techniques : tu peux mettre en cache la structure, et ainsi avoir par exemple un tableau de cette force :

$comments['id'] = array(
  'id' => array(
    ...
  ),
);

Ce qui te permet de faire qu’une seule requête (tu sélectionnes tous les commentaires pour la news), mais qui implique toujours la récursivité.

Etc.

Ahh… la méthode me semble assez bonne.
J’aurai pas pensé à appeler une fonction dans la fonction elle même O_o !

J’ai pas encore testé, mais logiquement ça devrait tourner :slight_smile:
Oui, “la récursivité”, le serveur doit pas trop aimer… je pensais limiter ça à 5 ou 10 réponses, m’enfin je verrai.

Par contre je ne comprends pas le “has_children” c’est censé correspondre à quoi ? L’id du commentaire d’origine auquel on répond ?
C’est pas bien important je pense, mais je ferais les tests demain… car il est quand même 1h là >_<

Merci Sans-Nom, tu m’as bien aidé :slight_smile:

Un booléen indiquant que le commentaire a des commentaires enfants. Idéal pour éviter de rappeler la fonction.