Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hierarchy commenting system php

i want to do discus/reddit/ like commenting system, i have an "id_answer" (set to 0 by defaut) field in my comment database and when user answer to another comment this field is the "id" of the parent comment.

I have the comments of the thread in an array but i dont know how to filter filter each loop for get something like this :

comment lvl 1 ($array[id_answer] is 0)

------- comment lvl 2 ($array[id_answer] is id_of_level_one_comment)

--------------- comment lvl 3 ...

like image 926
Tahola Avatar asked Oct 11 '11 18:10

Tahola


People also ask

How can we write comments in PHP?

Single-line PHP Comments To leave a single-line comment, type two forward slashes (//) followed by your comment text. All text to the right of the // will be ignored. You can also use a hash symbol (#) instead of // to make a single-line comment.

How do you store comments and replies in a database?

You could just use one table, which includes a ParentID field. If the record has no value, it is a comment, otherwise it is a reply (to either a comment or a reply). You could query the record's ParentID record (inspect it's ParentID) to see if this reply is to a comment or a reply.


1 Answers

Use three fields in your database;

  • "id", unique for each comment
  • "parent_id", which is either 0 (top level comment) or the "id" of the parent comment
  • "thread_id", which is the id of whatever you are commenting on

Let's say you want to show the comment tree for your news article with id "123"

When selecting from mysql, select everything with this thread_id:

SELECT id, parent FROM comments WHERE thread_id = 123

Then you should pre-parse your array to give the child comments to their parents, and use a recursive display to show each comment and its child list.

For exemple:

// getting the comments from mysql, I'm obviously not bothering
//   to check the return value, but in your code you should do it
$result = mysqli_query("SELECT id, parent FROM comments WHERE thread_id = 123");

$comments = array();
while ($row = mysqli_fetch_array($result)) {
  $row['childs'] = array();
  $comments[$row['id']] = $row;
}

// This is the array you get after your mysql query
// Order is non important, I put the parents first here simply to make it clearer.
/*
$comments = array(
    // some top level (parent == 0)
    1 => array('id' => 1, 'parent' => 0, 'childs' => array()),
    5 => array('id' => 5, 'parent' => 0, 'childs' => array()),
    2 => array('id' => 2, 'parent' => 0, 'childs' => array()),
    10 => array('id' => 10, 'parent' => 0, 'childs' => array()),
    // and some childs
    3 => array('id' => 3, 'parent' => 1, 'childs' => array()),
    6 => array('id' => 6, 'parent' => 2, 'childs' => array()),
    4 => array('id' => 4, 'parent' => 2, 'childs' => array()),
    7 => array('id' => 7, 'parent' => 3, 'childs' => array()),
    8 => array('id' => 8, 'parent' => 7, 'childs' => array()),
    9 => array('id' => 9, 'parent' => 6, 'childs' => array()),
);
*/

// now loop your comments list, and everytime you find a child, push it 
//   into its parent
foreach ($comments as $k => &$v) {
  if ($v['parent'] != 0) {
    $comments[$v['parent']]['childs'][] =& $v;
  }
}
unset($v);

// delete the childs comments from the top level
foreach ($comments as $k => $v) {
  if ($v['parent'] != 0) {
    unset($comments[$k]);
  }
}

// now we display the comments list, this is a basic recursive function
function display_comments(array $comments, $level = 0) {
  foreach ($comments as $info) {
    echo str_repeat('-', $level + 1).' comment '.$info['id']."\n";
    if (!empty($info['childs'])) {
      display_comments($info['childs'], $level + 1);
    }
  }
}

display_comments($comments);

This give the following result:

- comment 1
-- comment 3
--- comment 7
---- comment 8
- comment 5
- comment 2
-- comment 6
--- comment 9
-- comment 4
- comment 10

I leave the ORDER BY and such to you, as it should not pose any problem.

like image 145
Lepidosteus Avatar answered Oct 23 '22 00:10

Lepidosteus