无法在PHP

时间:2019-07-01 02:30:07

标签: php listview recursion treeview adjacency-list

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

我有两个表:“线程”和“帖子”,在这里我已简化了这些表的介绍。

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_id获取所有帖子,并按parent_id排序
  3. 对于每个线程,以某种方式(递归?)遍历此帖子列表并创建一个PHP有序列表,并适当缩进以显示父母与孩子之间的关系。

可悲的是,这是过去三天让我彻底陷入僵局的最后一步。以“线程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 01/07/01 09:10”我   意识到上面的示例在没有上下文的情况下看起来很奇怪。

老实说,我没有任何运行良好的代码可以在此处发布。在某一时刻,我有一个递归例程,该例程仅遍历最左腿,然后跳过第二个响应到第5条。

在另一点上,我有一个例程将所有节点重复显示和一式三份,并且缩进无法正常工作。

我很抱歉,这似乎应该是一个非常简单的练习,但是我只是努力使自己陷入困境,试图绕开它的递归性,再加上多个线程,等等。我是生命线,将不胜感激。

1 个答案:

答案 0 :(得分: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>";
        }
    }
}

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

recursive tree results