Я хотел бы сделать комментарии на моем сайте так:
<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>
Я прочитал следующую статью , однако она не использует <li>
. Так есть способ отображать комментарии, как я уже делал, с массивом? Благодарю.
$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') );
Я утверждаю, что в вашей таблице комментариев есть id, parent_id, comment, … и мое предложение выглядит следующим образом;
Выберите ваши комментарии;
$sql = "SELECT *FROM comments ORDER BY id DESC"; $rows = mysql_query($sql);
Следующий шаг – операции с массивами. Ниже вы можете увидеть следующий код и попробовать демо-версию здесь ;
$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);
с$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);
не$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);
Для демонстрации см. Здесь
BTW, в случае использования технологии Materialized Path вам не понадобится никакая рекурсия или вложенный массив или материал.
Просто простой линейный выход из базы данных.
Для этого просто создайте поле с именем path
в своей базе данных и заполните его всем родительским идентификатором, дополненным определенной длиной.
Скажем, пример дерева может выглядеть так:
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
поэтому, запрашивая вашу таблицу простым ORDER BY root DESC, path ASC
вы получите свое дерево как простой уже упорядоченный список
Эта функция будет нуждаться только в parent_id
и ключевом parent_id
присутствующем в массиве каждого комментария.
$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') );
Это вернет многомерный массив. Если у одного элемента нет детей, $comment['children']
будет равен NULL
, в противном случае будет прикреплен соответствующий массив детей.
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; }
с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; }
Я знаю, что его можно улучшить, но он работает, и я пока не обнаружил ошибок. Надеюсь, поможет!