问题
I would like to diplay comments on my site like this:
<li>Parent
<ul>
<li>child one</li>
<li>child two
<ul>
<li>grandchild</li>
<li>other grandchild</li>
</ul>
</li>
</ul>
<li>Another parent with no children</li>
<li>
I have read the following article, however it doesn't use <li>
. So is there a way to display comments like I've done before with an array like so? Thanks.
$comments = array(
array('id'=>1, 'parent_id'=>NULL, 'text'=>'Parent'),
array('id'=>2, 'parent_id'=>1, 'text'=>'Child'),
array('id'=>3, 'parent_id'=>2, 'text'=>'Child Third level'),
array('id'=>4, 'parent_id'=>NULL, 'text'=>'Second Parent'),
array('id'=>5, 'parent_id'=>4, 'text'=>'Second Child')
);
回答1:
I asssume your comment table has id, parent_id, comment, ... and my suggestion goes like this;
Select you comments like;
$sql = "SELECT *FROM comments ORDER BY id DESC";
$rows = mysql_query($sql);
And next step is array operations.You can see the following code below and try working demo here;
$rows = your_select_result;//I assumed that you have done these stuffs
$comments = $row;
/**
This is test data, please remove this array while you are
running own application.Since you will use the data one you get your db
**/
$comments = array(
1 => array('id' => 1, 'parent_id' => 0, 'childs' => array()),
2 => array('id' => 2, 'parent_id' => 0, 'childs' => array()),
3 => array('id' => 3, 'parent_id' => 0, 'childs' => array()),
5 => array('id' => 5, 'parent_id' => 0, 'childs' => array()),
11 => array('id' => 11, 'parent_id' => 0, 'childs' => array()),
17 => array('id' => 17, 'parent_id' => 0, 'childs' => array()),
23 => array('id' => 23, 'parent_id' => 0, 'childs' => array()),
28 => array('id' => 28, 'parent_id' => 0, 'childs' => array()),
4 => array('id' => 4, 'parent_id' => 1, 'childs' => array()),
6 => array('id' => 6, 'parent_id' => 1, 'childs' => array()),
8 => array('id' => 8, 'parent_id' => 2, 'childs' => array()),
9 => array('id' => 9, 'parent_id' => 2, 'childs' => array()),
7 => array('id' => 7, 'parent_id' => 3, 'childs' => array()),
12 => array('id' =>12, 'parent_id' => 7, 'childs' => array()),
13 => array('id' => 13, 'parent_id' => 12, 'childs' => array()),
);
/** Comment prepare start */
foreach ($comments as $k => &$v) {
if ($v['parent_id'] != 0) {
$comments[$v['parent_id']]['childs'][] =& $v;
}
}
unset($v);
foreach ($comments as $k => $v) {
if ($v['parent_id'] != 0) {
unset($comments[$k]);
}
}
/** Comment prepare end */
//Your indent pattern
function indent($size) {
$string = "";
for ($i = 0; $i < $size; $i++) {
$string .= "#";
}
echo $string;
}
function printComments($comments, $indent = 0) {
foreach ($comments as $comment) {
echo indent($indent + 1).' I am comment '.$comment['id']."\n";
if (!empty($comment['childs'])) {
printComments($comment['childs'], $indent + 1);
}
}
}
printComments($comments);
For demo please see here
回答2:
BTW, in case of using Materialized Path technique, you won't need no recursion nor nested array or stuff.
Just plain linear outpur from the database.
To do that just create a field named path
in your database and fill it with all the parent id's, padded to some considerabe length.
Say, example tree may look like
id 1 root path
id 3 root 1 path 000000001
id 5 root 1 path 000000001000000003
id 4 root 1 path 000000001
id 2 root path 000000002
id 6 root 2 path
so, querying your table by simple ORDER BY root DESC, path ASC
you will get your tree as a simple already ordered list
回答3:
This function will only need the parent_id
and id
key present in each comment's array.
$comments = array(
array('id'=>1, 'parent_id'=>NULL, 'text'=>'Parent'),
array('id'=>2, 'parent_id'=>1, 'text'=>'Child'),
array('id'=>3, 'parent_id'=>2, 'text'=>'Child Third level'),
array('id'=>4, 'parent_id'=>NULL, 'text'=>'Second Parent'),
array('id'=>5, 'parent_id'=>4, 'text'=>'Second Child')
);
This will return a multidimensional array. If one item has no children, $comment['children']
will equal NULL
, otherwise the respective array of children will be attached.
function arrangecomments($comments){
$tree = array();
/* We get all the parent into the tree array */
foreach ($comments as &$node) {
/* Note: I've used 0 for top level parent, you can change this to == 'NULL' */
if($node['parent_id']=='0'){
$tree[] = $node;
unset($node);
}
}
/* This is the recursive function that does the magic */
/* $k is the position in the array */
function findchildren(&$parent, &$comments, $k=0){
if (isset($comments[$k])){
if($comments[$k]['parent_id']==$parent['id']){
$com = $comments[$k];
findchildren($com, $comments); // We try to find children's children
$parent['children'][] = $com;
}
findchildren($parent, $comments, $k+1); // And move to the next sibling
}
}
/* looping through the parent array, we try to find the children */
foreach ($tree as &$parent) {
findchildren($parent, $comments);
}
return $tree;
}
I know it can be improved a lot, but it works, and I haven't found any bugs so far. Hope it helps!
来源:https://stackoverflow.com/questions/10370912/how-do-i-implement-nested-comments