За последние 24 часа нас посетил 85321 программист и 4735 роботов. Сейчас ищут 1813 программистов ...

Не могу вывести многомерный массив.

Тема в разделе "PHP для новичков", создана пользователем гендаль серый, 18 сен 2023.

  1. гендаль серый

    гендаль серый Новичок

    С нами с:
    20 янв 2023
    Сообщения:
    53
    Симпатии:
    0
    делаю выборку по parent_id, через форич выводятся комменты родители, а вот детей родителей уже долго не ммогу разобраться как вывести..дерево по задумке должно состоять из двух уровней - главные комменты и под ними в ряд все остальные...

    PHP:
    1. (
    2.     [0] => Array
    3.         (
    4.             [comment_id] => 109
    5.             [text_comm] => я тоже видел в новостях вчера
    6.             [post_id] => 251
    7.             [user_id] => 90
    8.             [parent_id] => 77
    9.             [answer_id] =>
    10.             [username] => mike
    11.         )
    12.  
    13.     [1] => Array
    14.         (
    15.             [comment_id] => 87
    16.             [text_comm] => у всех по разному - у кого то по новенькому, у других по старенькому, у кого как..
    17.             [post_id] => 251
    18.             [user_id] => 109
    19.             [parent_id] => 0
    20.             [answer_id] =>
    21.             [username] => henk moody
    22.         )
    23.  
    24.     [2] => Array
    25.         (
    26.             [comment_id] => 86
    27.             [text_comm] => в новостях видел ага жесть..
    28.             [post_id] => 251
    29.             [user_id] => 109
    30.             [parent_id] => 77
    31.             [answer_id] =>
    32.             [username] => henk moody
    33.         )
    34.  
    35.     [3] => Array
    36.         (
    37.             [comment_id] => 77
    38.             [text_comm] => да вон пожар на гаваях не слабый.
    39.             [post_id] => 251
    40.             [user_id] => 102
    41.             [parent_id] => 0
    42.             [answer_id] =>
    43.             [username] => ivan777
    44.         )
    45.  
    46. )
    вывод главных комментов делаю так, а с вложенным форичем чет не могу понять как что там сделать..буду благодарен специалистам если кто то подскажет как решить эту задачу и возможно ли без рекурсии.
    PHP:
    1. foreach($comments as $val){
    2.                 if ($val['parent_id'] == 0){
    3.                     $row = $val;
    4.                 require __DIR__ . '/../tpl/comment.php';
    5.                 }        
    6.             }
     
  2. гендаль серый

    гендаль серый Новичок

    С нами с:
    20 янв 2023
    Сообщения:
    53
    Симпатии:
    0
    переменная row приравнена к val, потому что в шаблонах комментов row..иначе аватарки слетают...скрипт аватаров привязан жестко к user_row..это потом я переделаю..
     
  3. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    Продемонстрируйте на примере оригинального массива(используйте var_export()), и что из него должно получиться
     
  4. гендаль серый

    гендаль серый Новичок

    С нами с:
    20 янв 2023
    Сообщения:
    53
    Симпатии:
    0
    у меня то выходила ошибка смещения строки при выводе ответов на комменты, то зацикливалось до зависания.
    в общем я не понял как использовать чисто parentid и id, добавил пока в таблицу левел - куда записывается тот же parentid, только ответы на ответы будут уже по левелу подцеплятся..сейчас немного продвинулся выводятся ответы, но как попало...
    вот эти ответы должны были ко второму комменту подцепится..странно
     

    Вложения:

    • Screenshot.png
      Screenshot.png
      Размер файла:
      19 КБ
      Просмотров:
      5
  5. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    Как вариант, храните "дерево" отдельно. Для экономии места, состоящее только из id сообщений.
     
    гендаль серый нравится это.
  6. гендаль серый

    гендаль серый Новичок

    С нами с:
    20 янв 2023
    Сообщения:
    53
    Симпатии:
    0
    это я понял, я и хотел сделать это одной функцией, но пришлось делать двумя - один форыч для выбора главных комментов, а второй я сделал в шаблоне самого коммента для вывода ответов..вроде заработало..но проблема я думаю в том что там кнопка раскрытия ответов срабатывает где не должна..сейчас надо как то проверять - если нет ответов на данный коммент чтоб кнопка тоже не показывалась..понимаю как это сделать, но не конкретно...забыл как то проверять можно есть в массиве ответы или нет..много гуглил каша в голове)
    --- Добавлено ---
    выводится нормально как надо, а глючит из-за кнопки..
     

    Вложения:

  7. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    Судя по скрину, у вас задумана неограниченная вложенность комментов.
    То есть, рано или поздно, скорее рано, в целях снижения затрат, вы придете к тому, что сгенерированное дерево нужно как-то кэшировать. Так, может, лучше сразу для топиков составлять "карту"? В xml или json
     
  8. гендаль серый

    гендаль серый Новичок

    С нами с:
    20 янв 2023
    Сообщения:
    53
    Симпатии:
    0
    выводится нормально как надо, а глючит из-за кнопки..
    два уровня сделано вроде..но надо сделать кэш наверно тоже погуглить)
     
  9. konkin_ivan

    konkin_ivan Активный пользователь

    С нами с:
    28 июн 2013
    Сообщения:
    9
    Симпатии:
    2
    Адрес:
    х Калиновский
    Код (Text):
    1.  
    2. //Для вывода комментариев родителей и дочерних на основе значения parent_id можно использовать цикл и условие. Вот пример кода на PHP:
    3.  
    4. function displayComments($comments, $parent_id = 0, $level = 0) {
    5.     foreach ($comments as $comment) {
    6.         if ($comment['parent_id'] == $parent_id) {
    7.             echo str_repeat("-", $level) . $comment['text_comm'] . "<br>";
    8.             displayComments($comments, $comment['comment_id'], $level + 1);
    9.         }
    10.     }
    11. }
    12.  
    13. // Пример использования
    14. $comments = [
    15.     [
    16.         "comment_id" => 109,
    17.         "text_comm" => "я тоже видел в новостях вчера",
    18.         "post_id" => 251,
    19.         "user_id" => 90,
    20.         "parent_id" => 77,
    21.         "answer_id" => "",
    22.         "username" => "mike"
    23.     ],
    24.     [
    25.         "comment_id" => 87,
    26.         "text_comm" => "у всех по разному - у кого то по новенькому, у других по старенькому, у кого как..",
    27.         "post_id" => 251,
    28.         "user_id" => 109,
    29.         "parent_id" => 0,
    30.         "answer_id" => "",
    31.         "username" => "henk moody"
    32.     ],
    33.     [
    34.         "comment_id" => 86,
    35.         "text_comm" => "в новостях видел ага жесть..",
    36.         "post_id" => 251,
    37.         "user_id" => 109,
    38.         "parent_id" => 77,
    39.         "answer_id" => "",
    40.         "username" => "henk moody"
    41.     ],
    42.     [
    43.         "comment_id" => 77,
    44.         "text_comm" => "да вон пожар на гаваях не слабый.",
    45.         "post_id" => 251,
    46.         "user_id" => 102,
    47.         "parent_id" => 0,
    48.         "answer_id" => "",
    49.         "username" => "ivan777"
    50.     ],
    51. ];
    52.  
    53. displayComments($comments);
    Результат выполнения кода будет выглядеть следующим образом:

    -у всех по разному - у кого то по новенькому, у других по старенькому, у кого как..
    --я тоже видел в новостях вчера
    -да вон пожар на гаваях не слабый.
    --в новостях видел ага жесть..

    Символ "-" в начале каждого комментария указывает на его уровень (глубину вложенности). Комментарии, у которых значение parent_id равно 0, считаются корневыми комментариями. Комментарии с parent_id равным ID других комментариев считаются дочерними комментариями для соответствующих родителей.
     
    гендаль серый нравится это.
  10. гендаль серый

    гендаль серый Новичок

    С нами с:
    20 янв 2023
    Сообщения:
    53
    Симпатии:
    0
    но это вроде рекурсии получается с неограниченными уровнями? если я правильно понял.
    я сделал двумя форычами два уровня. форычи не вложенные, один тот что выше выводит родительские комменты из массива, который взят из базы, а второй форыч так же из этого массива по условию выводит потомков..так то работает все вроде нормально, не знаю как будет при большом количестве пользователей конечно.
    а как попало у меня отображалось это из-за кнопки "показать ответы"..я сейчас отключил всю эту логику js и комменты нормально выводятся.
    сейчас думаю как сделать чтоб кнопка отображалась и показывала сколько ответов на комменты и если их нет, то и кнопка бы не выводилась..и кроме как делать еще один цикл с условием, на ум ничего не идет. и вот вопрос - можно ли столько циклов напихивать на страницу? это же каждый коммент будет с таким счетчиком..комментов конечно думаю штук по 50 выводить в будущем.
    за помощь спасибо!
     
  11. konkin_ivan

    konkin_ivan Активный пользователь

    С нами с:
    28 июн 2013
    Сообщения:
    9
    Симпатии:
    2
    Адрес:
    х Калиновский
    Да, этот код может работать с любой вложенностью комментариев. В функции displayComments происходит рекурсивный вызов функции самой себя для отображения подкомментариев. Это позволяет обрабатывать любую глубину вложенности.
    --- Добавлено ---
    Без использования рекурсии вы можете воспользоваться стеком для обхода всех комментариев вложенности. Вот пример решения с использованием стека:

    PHP:
    1. function displayComments($comments) {
    2.     $stack = [];
    3.  
    4.     // добавляем корневые комментарии в стек
    5.     foreach ($comments as $comment) {
    6.         if ($comment['parent_id'] == 0) {
    7.             $stack[] = [$comment, 0];
    8.         }
    9.     }
    10.  
    11.     while (!empty($stack)) {
    12.         list($comment, $level) = array_pop($stack);
    13.         echo str_repeat("-", $level) . $comment['text_comm'] . "<br>";
    14.      
    15.         // добавляем подкомментарии текущего комментария в стек
    16.         foreach ($comments as $subcomment) {
    17.             if ($subcomment['parent_id'] == $comment['comment_id']) {
    18.                 $stack[] = [$subcomment, $level + 1];
    19.             }
    20.         }
    21.     }
    22. }
    23.  
    24. // Пример использования
    25. $comments = [
    26.     // ...
    27. ];
    28.  
    29. displayComments($comments);
    В этом решении мы используем стек для хранения комментариев и их уровня вложенности. Сначала добавляем в стек корневые комментарии (те, у которых parent_id равен 0). Затем в цикле извлекаем комментарий из стека, отображаем его и добавляем в стек все его подкомментарии с увеличенным уровнем вложенности. Процесс повторяется, пока стек не станет пустым.
     
    гендаль серый нравится это.
  12. гендаль серый

    гендаль серый Новичок

    С нами с:
    20 янв 2023
    Сообщения:
    53
    Симпатии:
    0
    а куда здесь подставлять фалы шаблона комментов и ответов, у меня отдельные шаблоны сделаны, вывод изначально был расчитан не через таблицу...переделывать не хотелось бы.
     
  13. konkin_ivan

    konkin_ivan Активный пользователь

    С нами с:
    28 июн 2013
    Сообщения:
    9
    Симпатии:
    2
    Адрес:
    х Калиновский
    Было бы хорошо, если Вы сделаете более конкретное описание задачи или же оформите прототип кода на Github например. Сложно представить в полном объеме, что у Вас там.
     
  14. гендаль серый

    гендаль серый Новичок

    С нами с:
    20 янв 2023
    Сообщения:
    53
    Симпатии:
    0
    в общем я сделал что то рабочее..вроде работает. пока оставлю так, в будущем может сделаю по другому