Друзья. Подскажите, есть ли какое-либо решение для пагинации древовидных комментариев?
Необходимо сделать систему общения, похожую на эту:
shikimori.org (1 родительский комментарий, остальные со вложенностью 2 уровня) с ПАГИНАЦИЕЙ! Т.е. должна быть кнопка "отобразить еще комментарии" как у первого уровня, так и у второго уровня.
Из всего прочитанного в интернете нашел два варианта решений:
Первый вариант:
www.9lessons.info/2011/05/facebook-wall-script-wit...
Сделать две таблицы в БД:
1 таблица - все комментарии первого уровня.
2 таблица - все комментарии второго уровня с ключом ID от первого уровня, по которому они подгружаются к комментарию первого уровня.
т.е.
select комменты первого уровня
while() {
if (есть ответы на коммент) {
select комменты второго уровня where parent = id коммента первого уровня
}
}
Но данная реализация очень ресурсозатратна, верно? Делать Select в цикле while, как я понимаю, не есть хорошо?
Планируется 10 комментариев первого уровня на страницу.. Если у этих 10 комментариев будут дочерние комментарии, то запросов будет 11.
Плюсы данной реализации:
В первом запросе, когда SELECT всех комментов первого уровня, можно задать четкий LIMIT. Также можно задать четкий LIMIT у дочерних комментариев. Эти LIMITы нужны для пагинации (возможности подгружать больше комментариев, как тут:
easycaptures.com/fs/uploaded/1045/7634907040.jpg)Минусы: Высокая нагрузка на БД ?!
-----------------------------------------------
Второй вариант:
Одна таблица со всеми комментариями.
Делаем всего 1 запрос к БД - SELECT всех комментариев к новости вместе с дочерними с сортировкой по дате.
У нас получается массив со всеми комментариями к новости.
Обрабатываем данный массив функцией рекурсии:
function dotree(&$comments, $parentComment = 0, $level = 0, $count = null){
if (is_array($comments) && count($comments)){
$return = array();
if (is_null($count)){
$c = count($comments);
}else{
$c = $count;
}
for($i=0;$i<$c;$i++){
if (!isset($comments[$i])) { continue; }
$comment = $comments[$i];
$parentId = $comment['parent'];
if ($parentId == $parentComment){
$comment['level'] = $level;
$commentId = $comment['id'];
$return[] = $comment;
unset($comments[$i]);
while ($nextReturn = dotree($comments, $commentId, $level+1, $c)){
$nextReturn = array_reverse($nextReturn);
$return = array_merge($return, $nextReturn);
}
}
}
return $return;
}
return false;
}
Получаем массив со всеми комментариями к новости, вида:
1
1.1
1.2
2
3
3.1
3.2
3.3
Как вывести первые 3 родительских комментариев с дочерними подкомментариями? Если поставить LIMIT 3 в этот единственный запрос, то выберется три первых записи, отсортированные по дате. Не факт, что там будут 3 родительских.
Так как разумно сделать возможность пагинации (навигации) по комментариям, чтобы можно было подгружать большее кол-во комментариев с доп. запросов через json?
Пару дней ищу разумное решение, пожалуйста, подскажите кто-нибудь.