0

我正在构建一个非常简单的线程消息系统,主要是为了我网站的用户在我扩展网站功能时向我和彼此交流错误和问题。但是,我没有运气创建每个线程的正确嵌套列表。

我有两个表:Threads 和 Posts,我已经对其进行了简化以便在此处进行演示。

Threads 表大致如此,按最近修改的线程排序:

+----+-----------------+---------------------+
| 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 |
+----+-----------------+---------------------+

Posts 表大致如下:

+----+------+-----+----------------------------------+
| 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

请注意,响应按发布日期排序(最近的在前),当然对于后续线程,我希望缩进再次回到零位置。

添加以澄清意图:在生产中,每个帖子都是一个链接,可以打开以显示消息的全文。响应将是相同的“线程名称”,并附加了用户和日期。因此,例如,踏板可能会显示“登录期间发现错误”,而我的回复(第一个孩子)会显示:“登录期间发现错误 - Chris Conlee 19/07/01 09:10”我意识到上面的示例看起来很奇怪语境。

老实说,我没有任何运行良好的代码可以在这里发布。有一次,我有一个递归例程,它只遍历最左边的腿,然后跳过对帖子 5 的第二个响应。

在另一点上,我有一个例程显示所有节点一式三份,并且缩进从未正常工作。

我深表歉意,因为它似乎应该是一个非常简单的练习,但我只是让自己陷入困境,试图了解它的递归性质,再加上多线程等。如果有人能给我一条生命线将不胜感激。

4

1 回答 1

0

好吧,我终于放慢了脚步,逐个元素地迭代并弄清楚了。

相对于给定线程提供一组帖子,例如:

[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>";
        }
    }
}

递归遍历树并返回类似于以下的结果:

递归树结果

于 2019-07-03T01:57:01.200 回答