Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Древовидные комментарии
 
 автор: dirol   (10.02.2011 в 17:47)   письмо автору
 
 

Здравствуйте.
Подскажите пожалуйста нормальные примеры древовидных комментариев
нашел один пример но как в нем правильно и грамотно все вывести не понял


Вывожу часть данных из БД:



$res = mysqlQuery("SELECT `id`, `reply`, `text` 
                        FROM `tbl` ");
 
    // reply - родительский id
 
    if(mysql_num_rows($res) > 0)
    {
      while($row = mysql_fetch_assoc($res))
      {
        $tree[$row['reply']][$row['id']] = $row['text'];
      }
    }


Прохожусь по всему дереву:

function ShowTree($tree, $pid=0)
{
  $data = array(); 
  
  foreach($tree as $id=>$root)
  {
    if($pid!=$id)
      continue;
 
      if(count($root))
      {
        foreach($root as $key => $title)
        {
         // echo '<h1>'. $key .'</h1>';
         
         if(count($tree[$key]))
           ShowTree($tree,$key);
        }
      }
 
   }
 
 return $data; 

 
$dt = ShowTree($tree);



-- --------------------------------------------------------

--
-- Структура таблицы `comments`
--

CREATE TABLE IF NOT EXISTS `comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `created` datetime NOT NULL,
  `content` text,
  `post_id` int(11) NOT NULL,
  `parent_id` int(11) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;

--
-- Дамп данных таблицы `comments`
--

INSERT INTO `comments` (`id`, `username`, `created`, `content`, `post_id`, `parent_id`) VALUES
(1, 'q_sty***', '2009-07-06 19:22:18', 'Как-то на «гетафрилансере» нашёл постоянного заказчика на джумлу и с тех пор все сайты делаю на ней. Но очень интересно было почитать про интернет-магазины: это мой осноной «доход».\nЕсть ли для вордпресса что-нибудь хотя бы чуть чуть похожее на virtuemart?', 1, 0),
(2, 'gho***', '2009-07-06 19:22:48', 'не видел VirtueMart, но лучший магаз под WP это действительно eCommerce, как справедливо отмечено в статье в п.10', 1, 1),
(3, 's***', '2009-07-06 19:23:03', 'Вряд ли найдете что нибудь типа VirtueMart, хотя нужен ли большинству магазин с такой функциональностью как VirtueMart', 1, 1),
(4, 'q_sty***', '2009-07-06 19:23:15', 'Удивительно, но моим клиентам — да. Мы действительно почти полностью используем все фишечки и плюшечки.', 1, 3),
(5, '***', '2009-07-06 19:23:33', 'Очень удивил 1-й пункт — или переводчик или автор статьи наверно забыл, что такое статический сайт и что такое динамический сайт?', 1, 0),
(6, 's***', '2009-07-06 19:23:56', 'С одной стороны вы правы, а с другой стороны… Как назвать сайт на CMS, но на котором нет постоянно изменяемой\\дополняемой информации?', 1, 5),
(7, 'egos***', '2009-07-06 19:24:38', 'Ну да давайте минусовать.\nДавай возьмем кофеварку, немного пошаманим и сделаем с нее простой электро чайник.\nЭто ведь так удобно, и оригинально.', 1, 2),
(8, 'm***', '2009-07-06 19:24:49', 'Кому-то недают спокойно жить лавры Emacs. Напишите уже по WordPress кипятилку для чайника. А то приходится по 2 раза на кухню ходить.', 1, 7),
(9, 'm***', '2009-07-06 19:25:08', '*не дают. Идиот!', 1, 1);




как их выводить правильно ? чтобы смешались

  Ответить  
 
 автор: Красная_шляпа   (10.02.2011 в 18:24)   письмо автору
 
   для: dirol   (10.02.2011 в 17:47)
 

все комментарии загоняешь в массив а потом рекурсивно выводишь

  Ответить  
 
 автор: Косорылый   (10.02.2011 в 22:02)   письмо автору
 
   для: Красная_шляпа   (10.02.2011 в 18:24)
 

Опять страшное слово рекурсия.(с немеренным к-вом запросов) :)))
>>>для dirol
Древовидные комментарии трудно воспринимаются + рвут разметку (особенно на экранах малого разрешения ,от 800 и меньше)
Лучше делать комментарии на конкретное сообщение (выделяя ,типо: комментировать : как сообщение , вопрос и т.д. )

  Ответить  
 
 автор: Красная_шляпа   (10.02.2011 в 23:14)   письмо автору
 
   для: Косорылый   (10.02.2011 в 22:02)
 

> все комментарии загоняешь в массив

одним запросом выбираешь все комментарии треда, строишь вложенные массивы(nested sets) и рекурсивно его


<?php

// $a - массив 2х мерный

$ClassName "B";

    function 
PrintTree($ParentId$level) {
    global 
$ClassName$session_id$a$thread_id;

        if (
$ClassName == "C") {
            
$ClassName "B";
        }
        else {
            
$ClassName "C";
        }

        ++
$level;
    
$childs = array();
        foreach(
$a as $v) {
            if (
$v[1] == $ParentId) {
        
$childs[] = $v;
            }
        }

    if (!empty(
$childs)) {
            foreach (
$childs as $v) {

                echo 
"<tr>";
                echo 
"<td class='$ClassName'>";
                echo 
"<div style='margin-left: ".($level 10)."px; padding: 7px 14px; overflov: auto;'>";
        echo 
"Автор: <a href='#'>".$v[2]."</a><br>";
                echo 
"IP-адресс: <a href='#'>".$v[3]."</a><br>";
                echo 
"Дата/время: ".date("d.m.Y H:i:s", (int) $v[4])."<br>";
                echo 
_print($v[8])."<br>";
                if (!empty(
$v[5])) {
                    echo 
"<br>Отредактировал(а) в последний раз: <b>$v[6]</b> ".date("d.m.Y в H:i:s", (int) $v[5])."<br>";
                    echo 
"Изменено: $v[7] раз";
                    
$num = (int) $v[7];
                    
$i = ($num 20) ? $num 10 $num;
                    if (
$i and $i 5) {
                        echo 
"а";
                    }
                    echo 
"<br>";
                }
                echo 
"[ <a href='{$_SERVER["PHP_SELF"]}?inc=add_post&amp;thread_id=$thread_id&amp;parent_id=$v[0]'>Ответить</a> ";


                
////////////////////////////////////////////////////////////////
                // var_dump($session_id);
                
if ($_SESSION[$session_id]["level"] >= 999 or isMyPost((string) $thread_id, (string) $v[0])) {
                    echo 
"| <a href='{$_SERVER["PHP_SELF"]}?inc=edit_post&amp;thread_id=$thread_id&amp;post_id=$v[0]'>Изменить</a> ";
                }
                
////////////////////////////////////////////////////////////////

                
echo "]</div>";
                echo 
"</td>";
                echo 
"</tr>\n";

        
PrintTree($v[0], $level);
                if (
$level $ParentId 1) { // !?
                    
--$level;
                }
            }
    }
    }
    
PrintTree(0,0);

    echo 
"</table>\n";



из моего старого. Автор пускай сам разбирается.

  Ответить  
 
 автор: Красная_шляпа   (10.02.2011 в 23:19)   письмо автору
 
   для: Красная_шляпа   (10.02.2011 в 23:14)
 

.

  Ответить  
 
 автор: lElectroHardl   (11.02.2011 в 09:20)   письмо автору
 
   для: Красная_шляпа   (10.02.2011 в 23:14)
 

Может я чего-то не доганяю, но не легче ли сделать древовидность путем 2-уровнего цикла?
Т.е. выводиться 1-й коммент и ниже, в цикле, все комменты, где "id_parrent == [id_коммента_родителя]". И так далее. А что бы было видно куда какие комменты относятся, можно использовать ЦСС (margin-left).

Ах, да, что бы комменты не рушили структуру, можно сделать следующие: если дочерних комментов больше 10, то при 11 и далее комментах не прибавлять margin-left, дабы лишние комменты шли не по диагонали, а по вертикали.

  Ответить  
 
 автор: psychomc   (11.02.2011 в 10:47)   письмо автору
 
   для: lElectroHardl   (11.02.2011 в 09:20)
 

может быть, лучше сделать просто нерушимую структуру?

  Ответить  
 
 автор: lElectroHardl   (11.02.2011 в 18:27)   письмо автору
 
   для: psychomc   (11.02.2011 в 10:47)
 

Кто сказал, что структура, что описана выше - рушима? И в чем вы видите рушимость?

  Ответить  
 
 автор: dirol   (16.02.2011 в 21:05)   письмо автору
 
   для: lElectroHardl   (11.02.2011 в 18:27)
 

нашел классный рабочий пример


<?php #Дерево разделов. 
#Выбор _всех_ разделов. 
$parts_query mysql_query("SELECT id, parent_id, name FROM sections 
ORDER BY ord ASC"
$mysql); 
#Если есть хоть какие-то разделы. 
if ($parts_query && mysql_num_rows($parts_query) > 0) { 
  
$parts_array = array(); 
  
$part_data 0
  
#Распихиваем полученные данные в массив. 
  #Попутно для красоты заменяем возможные пустые поля "parent_id" 
  #(для разделов, не имеющих родителя) на ноль. 
  
while($part_data mysql_fetch_row($parts_query)) { 
    
$part_data[1] = isset($part_data[1]) && $part_data[1] > 
$part_data[1] : 0
    
array_push($parts_array$part_data); 
  } 
  
mysql_free_result($parts_query); 

#Это функция, рекурсивно вызывающаяся для формирования дерева разделов. 
function get_hierarchy($parts_array$parent_id) { 
  
#Кол-во записей на текущем уровне. Нужно для того, чтобы по уму 
  #выводить <ul>...</ul> для этого уровня, т.е. если записей нет, то и 
  #эти тэги не нужны. 
  
$this_count 0
  foreach (
$parts_array as $idx => $element) { 
    
#Выводим раздел текущего уровня (тот, чей идентификатор родителя 
    #равен заданному при вызове функции ($parent_id)). 
    
if ($element[1] == $parent_id) { 
      
$this_count++; 
      
#Вывод HTML очередного пункта меню. 
      
if ($this_count == 1) echo("<ul>"); 
      echo(
"<li><a 
href=\"./parts.php?id="
.$element[0]."\">".$element[2]."</a>"); 
      
#Самое интересное: функция вызывает саму себя для формирования 
      #дочерних узлов текущего раздела. 
      
get_hierarchy($parts_array$element[0]); 
      echo(
"</li>"); 
    } 
  } 
  if (
$this_count 0
    echo(
"</ul>"); 

#Начальный вызов: идентификатор родительского раздела равен 
#нулю, т.е. "родителя нет". 
echo(get_hierarchy($parts_array0)); 
?>

  Ответить  
 
 автор: Косорылый   (16.02.2011 в 21:48)   письмо автору
 
   для: dirol   (16.02.2011 в 21:05)
 

Может и ошибаюсь но с первого взгляда список (как html ul --li)будет неправельным

  Ответить  
 
 автор: dirol   (24.03.2011 в 13:34)   письмо автору
 
   для: Косорылый   (16.02.2011 в 21:48)
 

Помогите подправить вывод комментариев


CREATE TABLE IF NOT EXISTS `cms_comment` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `cid` int(11) NOT NULL DEFAULT '0',
  `modul` varchar(60) NOT NULL DEFAULT '',
  `date` datetime DEFAULT NULL,
  `uid` int(11) NOT NULL DEFAULT '0',
  `name` varchar(25) NOT NULL DEFAULT '',
  `host_name` varchar(60) DEFAULT NULL,
  `comment` text NOT NULL,
  `status` int(1) NOT NULL,
  `votes` int(10) NOT NULL,
  `totalvotes` int(11) NOT NULL,
  `parentid` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `cid` (`cid`),
  KEY `uid` (`uid`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=22 ;

--
-- Дамп данных таблицы `cms_comment`
--

INSERT INTO `cms_comment` (`id`, `cid`, `modul`, `date`, `uid`, `name`, `host_name`, `comment`, `status`, `votes`, `totalvotes`, `parentid`) VALUES
(1, 0, '', '2009-06-19 19:44:49', 1, 'ФИО', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(2, 0, '', '2011-03-19 19:44:49', 1, 'amirSamir', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(3, 0, '', '2011-03-19 19:44:50', 1, 'юзверь', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(4, 0, '', '2011-03-19 19:45:49', 1, 'кукушка', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(5, 0, '', '2011-03-19 19:45:55', 1, 'приммар', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(6, 0, '', '2011-03-19 19:46:55', 1, 'юзверь2', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(7, 0, '', '2011-03-19 19:46:00', 1, 'профессор', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(8, 0, '', '2011-03-12 19:50:00', 1, 'геолог', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(9, 0, '', '2011-03-12 19:50:05', 1, 'заолог', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(10, 0, '', '2011-03-12 19:50:15', 1, 'трактор', NULL, 'Пробный текст коментария', 0, 0, 0, 4),
(11, 0, '', '2011-03-12 19:58:00', 1, 'велик', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(12, 0, '', '2011-03-13 01:50:00', 1, 'текеок', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(13, 0, '', '2011-03-13 09:50:00', 1, 'телек', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(14, 0, '', '2009-06-19 19:44:49', 1, 'юзверь3', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(15, 0, '', '2009-06-19 19:44:49', 1, 'юзверь4', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(16, 0, '', '2009-06-19 19:44:49', 1, 'юзверь5', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(17, 0, '', '2009-06-19 19:44:49', 1, 'юзверь6', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(18, 0, '', '2009-06-19 19:44:49', 1, 'ФИО', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(19, 0, '', '2011-03-24 13:12:49', 1, 'последний', NULL, 'Пробный текст коментария', 0, 0, 0, 14),
(20, 0, '', '2009-06-19 19:44:49', 1, 'ФИО', NULL, 'Пробный текст коментария', 0, 0, 0, 0),
(21, 0, '', '2009-06-19 19:44:49', 1, 'ФИО', NULL, 'Пробный текст коментария', 0, 0, 0, 14);




$sql2 = mysql_connect('localhost','new','po6Ahn5I');
    mysql_query("SET NAMES cp1251");
    mysql_select_db('new', $sql2);

$parts_query = mysql_query("SELECT id, cid, UNIX_TIMESTAMP(date) as formatted, uid, name, host_name, comment, votes, parentid FROM cms_comment ORDER BY id ASC", $sql2);
#Если есть хоть какие-то разделы.
if ($parts_query && mysql_num_rows($parts_query) > 0) {
  $parts_array = array();
  $part_data = 0;
  #Распихиваем полученные данные в массив.
  #Попутно для красоты заменяем возможные пустые поля "parent_id"
  #(для разделов, не имеющих родителя) на ноль.
  while($part_data = mysql_fetch_row($parts_query)) {
    $part_data[8] = isset($part_data[8]) && $part_data[8] > 0 ?
    $part_data[8] : 0;
    array_push($parts_array, $part_data);

  }
  mysql_free_result($parts_query);
}


#Это функция, рекурсивно вызывающаяся для формирования дерева разделов.
function get_hierarchy($parts_array, $parent_id) {
  #Кол-во записей на текущем уровне. Нужно для того, чтобы по уму
  #выводить <ul>...</ul> для этого уровня, т.е. если записей нет, то и
  #эти тэги не нужны.
  $this_count = 0;
  $a=1;
  foreach ($parts_array as $idx => $element) {
    #Выводим раздел текущего уровня (тот, чей идентификатор родителя
    #равен заданному при вызове функции ($parent_id)).
    if ($element[8] == $parent_id) {
      $this_count++;
      #Вывод HTML очередного пункта меню.
      if ($this_count == 1) echo("<ul>");
      echo("<li> -$a- <a href=\"./parts.php?id=".$element[0]."\">".$element[4]."</a> ".$element[2]."");

      #Самое интересное: функция вызывает саму себя для формирования
      #дочерних узлов текущего раздела.
      get_hierarchy($parts_array, $element[0]);
      $a++;
      echo("</li>");
    }
  }
  if ($this_count > 0)
  echo("</ul>");
}
#Начальный вызов: идентификатор родительского раздела равен
#нулю, т.е. "родителя нет".
echo(get_hierarchy($parts_array, 0));


и вот тут шаблон вывода коментариев


<div class="dh2 dh2komments"><h2>Комментарии</h2> <span>(38)</span></div>
                
                <div class="comments"> 
                
                    <div class="comment epic45">
                        <form action="">
                            <div>
                                <span class="plus">+6</span>
                                <input class="krestik" type="submit" value="" />
                                <input class="galochka" type="submit" value="" />
                            </div>
                        </form>
                        
                        <div class="commenttop">
                            <div class="avatar"><div></div></div>
                            
                            <a href="#">epic45</a>,
                            <span>27 февраля 2011, 21:52<span>
                        </div>
                        
                        <p>Салачик в ущелье у подножия Кырк-Ера и селение</p>
                    </div>
                    
                    <div class="comment com2 Alexey">
                        <form action="">
                            <div>
                                <span class="nul">0</span>
                                <input class="krestik" type="submit" value="" />
                                <input class="galochka" type="submit" value="" />
                            </div>
                        </form>
                        
                        <div class="commenttop">
                            <div class="avatar"><div></div></div>
                            
                            <a href="#">Alexey</a>,
                            <span>27 февраля 2011, 21:52<span>
                        </div>
                        
                        <p>ервой половине XVI в. среди них было три основных: город-крепость</p>
                    </div>
                    
                    <div class="comment com3 epic45">
                        <form action="">
                            <div>
                                <span class="minus">-13</span>
                                <input class="krestik" type="submit" value="" />
                                <input class="galochka" type="submit" value="" />
                            </div>
                        </form>
                        
                        <div class="commenttop">
                            <div class="avatar"><div></div></div>
                            
                            <a href="#">epic45</a>,
                            <span>27 февраля 2011, 21:52<span>
                        </div>
                        
                        <p>
                            Салачик в ущелье у подножия Кырк-Ера и селение Эски-Юрт при<br />
                            выходе из долины. В Салачике и Кырк-Ере со времен Золотой Орды существовали административные центры. На рубеже XV и XVI веков хан Менгли I Герай развернул в Салачике городское
                        </p>
                    </div>
                    
                    <div class="comment Alexey">
                        <form action="">
                            <div>
                                <span class="plus">+1</span>
                                <input class="krestik" type="submit" value="" />
                                <input class="galochka" type="submit" value="" />
                            </div>
                        </form>
                        
                        <div class="commenttop">
                            <div class="avatar"><div></div></div>
                            
                            <a href="#">Alexey</a>,
                            <span>27 февраля 2011, 21:52<span>
                        </div>
                        
                        <p>Салачик в ущелье у подножия Кырк-Ера и селение Эски-Юрт при</p>
                    </div>
                </div>


помогите подставить верстку в скрипт вывода коментариев

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования