Проблемы с построением вложенного списка потоковых сообщений в PHP - PullRequest
0 голосов
/ 01 июля 2019

Я создаю ОЧЕНЬ простую систему многопоточных сообщений, в первую очередь для того, чтобы пользователи моего сайта сообщали об ошибках и проблемах мне и друг другу по мере расширения функциональности моего сайта. Но мне не повезло в создании правильно вложенного списка каждого потока.

У меня есть две таблицы: темы и сообщения, которые я упростил для представления здесь.

Таблица нитей в основном похожа на такую, упорядоченную самой последней измененной веткой:

+----+-----------------+---------------------+
| id | thName          | thModified          |
+----+-----------------+---------------------+
| 5  | Thread Number 5 | 2019-06-29 20:54:59 |
+----+-----------------+---------------------+
| 4  | Thread Number 4 | 2019-06-29 20:45:22 |
+----+-----------------+---------------------+
| 3  | Thread Number 3 | 2019-06-29 20:44:20 |
+----+-----------------+---------------------+
| 2  | Thread Number 2 | 2019-06-29 20:43:00 |
+----+-----------------+---------------------+
| 1  | Thread Number 1 | 2019-06-29 20:39:25 |
+----+-----------------+---------------------+

Таблица сообщений выглядит примерно так:

+----+------+-----+----------------------------------+
| Id | thID | pID | postMessage                      |
+----+------+-----+----------------------------------+
| 1  | 1    | 0   | First message of thread number 1 |
+----+------+-----+----------------------------------+
| 2  | 2    | 0   | First message of thread number 2 |
+----+------+-----+----------------------------------+
| 3  | 3    | 0   | First message of thread number 3 |
+----+------+-----+----------------------------------+
| 4  | 4    | 0   | First message of thread number 4 |
+----+------+-----+----------------------------------+
| 5  | 5    | 0   | First message of thread number 5 |
+----+------+-----+----------------------------------+
| 6  | 5    | 5   | First response to post 5         |
+----+------+-----+----------------------------------+
| 7  | 5    | 5   | Second response to post 5        |
+----+------+-----+----------------------------------+
| 8  | 5    | 6   | First response to post 6         |
+----+------+-----+----------------------------------+
| 9  | 1    | 1   | First response to post 1         |
+----+------+-----+----------------------------------+

Если каждое сообщение связано с потоком в другой таблице, а отношения родитель / потомок определяются в этой таблице путем анализа столбца parentID. Сообщения с "0" в качестве родителя являются корневыми узлами.

Мой основной план атаки таков:

  1. Получить все темы, отсортированные по самым последним
  2. Для каждой темы получить ВСЕ сообщения, соответствующие thread_ids, отсортированные по parent_id
  3. Для каждого потока, каким-то образом (рекурсивно?) Пройти через этот список сообщений и создать упорядоченный список PHP с правильными отступами, показывающими отношения между родителями и детьми.

К сожалению, это последний шаг, который привел меня в тупик за последние 3 дня. Используя «Поток 5» в качестве примера, после шага 2 у меня есть массив, который выглядит следующим образом:

    [0] => Array
        (
            [post_id] => 5
            [thread_id] => 5
            [parent_id] => 0
            [user_id] => 9
            [post_message] => First message of thread number 5
            [post_created] => 2019-06-29 20:54:59
            [thread_title] => Thread Number 5
        )

    [1] => Array
        (
            [post_id] => 6
            [thread_id] => 5
            [parent_id] => 5
            [user_id] => 9
            [post_message] => First response to post 5
            [post_created] => 2019-06-29 21:39:00
            [thread_title] => Thread Number 5
        )

    [2] => Array
        (
            [post_id] => 7
            [thread_id] => 5
            [parent_id] => 5
            [user_id] => 9
            [post_message] => Second response to post 5
            [post_created] => 2019-06-29 21:52:00
            [thread_title] => Thread Number 5
        )

    [3] => Array
        (
            [post_id] => 8
            [thread_id] => 5
            [parent_id] => 6
            [user_id] => 0
            [post_message] => First response to post 6
            [post_created] => 2019-06-29 21:55:00
            [thread_title] => Thread Number 5
        )

Из этого массива я хотел бы создать вложенный список, который выглядит примерно так:

Thread Number 5 - First message of thread number 5
    Thread Number 5 - Second response to post 5
    Thread Number 5 - First response to post 5
        Thread Number 5 - First response to post 6

Обратите внимание, что ответы сортируются по дате публикации (сначала самой последней), и, конечно, для последующих тем я бы хотел, чтобы отступы снова возвращались в нулевое положение.

Добавлено для уточнения намерений: при создании каждого поста будет ссылка, которая открывается для отображения полного текста сообщения. Ответы будут то же самое «название темы» с добавлением пользователя и даты Так, например, протектор может прочитать «Обнаружена ошибка при входе в систему» ​​и мой ответ (1-й ребенок) будет читать: «Обнаружена ошибка при входе в систему - Крис Конли 19/07/01 09:10» I понял, что приведенный выше пример кажется странным без контекста.

Честно говоря, у меня нет кода, который работает достаточно хорошо, чтобы опубликовать его здесь. В какой-то момент у меня была рекурсивная процедура, которая проходила только через самую левую ногу, а затем пропустила второй ответ на пост 5.

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

Я приношу свои извинения, так как кажется, что это должно быть ОЧЕНЬ простое упражнение, но я просто превратил себя в узлы, пытаясь разобраться в его рекурсивной природе, в сочетании с несколькими нитями и т. Д. Если кто-то может бросить мне спасательный круг, это было бы ПОГОДНО оценено.

1 Ответ

0 голосов
/ 03 июля 2019

Ну, наконец-то я замедлил шаг, прошел элемент итерации за элементом и понял это.

Подача массива сообщений, относящихся к заданному потоку, например:

[0] => Array
        (
            [post_id] => 5
            [thread_id] => 5
            [parent_id] => 0
            [user_id] => 9
            [post_message] => First message of thread number 5
            [post_created] => 2019-06-29 20:54:59
            [thread_title] => Thread Number 5
        )

    [1] => Array
        (
            [post_id] => 6
            [thread_id] => 5
            [parent_id] => 5
            [user_id] => 9
            [post_message] => First response to post 5
            [post_created] => 2019-06-29 21:39:00
            [thread_title] => Thread Number 5
        )

    [2] => Array
        (
            [post_id] => 7
            [thread_id] => 5
            [parent_id] => 5
            [user_id] => 9
            [post_message] => Second response to post 5
            [post_created] => 2019-06-29 21:52:00
            [thread_title] => Thread Number 5
        )

    [3] => Array
        (
            [post_id] => 8
            [thread_id] => 5
            [parent_id] => 6
            [user_id] => 0
            [post_message] => First response to post 6
            [post_created] => 2019-06-29 21:55:00
            [thread_title] => Thread Number 5
        )

В следующий метод:

public function buildForum($postsToThread, &$forum, $parent_id = 0) {
    foreach ($postsToThread as $post) {
        $time = strtotime($post['post_created']);
        $tmpCurrentAuthorName = $this->getPostAuthor($post['user_id']);
        $tmpCurrentThreadTitle = $post['thread_title'];
        $tmpCurrentPostDate = date("M d, Y g:i A", $time);
        if ($post['parent_id'] == $parent_id) {
            $forum .= "<ol><li><a href='/freetools/forumViewPost/" .$post['post_id'] . "'>" . $tmpCurrentThreadTitle .= " by " . $tmpCurrentAuthorName . "</a> on " . $tmpCurrentPostDate . "</li>";
            $parent_id = $post['post_id'];
            $this->buildForum($postsToThread, $forum, $parent_id);
            $parent_id = $post['parent_id'];
            $forum .= "</ol>";
        }
    }
}

Рекурсивно обходит дерево и возвращает результат, подобный следующему:

recursive tree results

...