如何构建分层评论树?

时间:2013-08-27 16:07:42

标签: php sql tree comments hierarchical

我正在使用评论系统,我遇到了一些问题。我正在建立一个像这样的分层评论系统:

注释1

- 注释2

---- comment4

将comment3

- comment5

我用来做这个查询:

$sql = "SELECT id, parent_id, name, comment,
    DATE_FORMAT(add_date, '%d %M %Y %H:%i') as add_date
    FROM comments  ORDER BY id DESC";

然后使用此功能:

function mapTree( $dataset )
{
    $tree = array();

    foreach ($dataset as $id=>&$node)
    {
        if (!$node['parent_id'])
        {
            $tree[$id] = &$node;
        }
        else
       {
            $dataset[$node['parent_id']]['childs'][$id] = &$node;
        }
    }

    return $tree;
}

但如果我想将评论数量限制为3或5或eth。我再也没有树了:

示例:

SELECT id, parent_id, name, comment,
        DATE_FORMAT(add_date, '%d %M %Y %H:%i') as add_date
        FROM comments LIMIT 2

注释1

- 注释2

我正在删除有父ID的评论。

你可以帮我解决一下或者用其他方法来构建评论树脚本吗?

1 个答案:

答案 0 :(得分:0)

我认为要使代码生效,数据集ID需要与节点ID匹配。除此之外,它似乎有效。

按照约会或父母身份,我最好订购。 (自动递增ID实际上可能不是按日期顺序排列。)

如果您的SQL具有add_date的ORDER,并且您限制了查询,则稍后对早期评论的回复可能无法放在较早的帖子中。我认为是你的问题。

我会问你为什么要首先在那里使用LIMIT?我假设它是用于评论分页。这可能表明允许太多评论(想到这里的网页评论)。您可以拥有最大数量的允许提交。也许让评论树更具可读性的更好方法是使用可折叠线程而不是使用分页。

您可能希望在表中添加一个线程/树/主题ID,并在SQL中添加相应的WHERE子句。

我必须为您的数据集添加索引才能使代码正常工作:

<?php

// Similar format to rowsets from a database...
// node is an array containing: id, parent id, comment
$commentRows = array(
    array('a', '0', 'Hi, great stuff.'),
    array('b', 'a', 'No, not really!'),
    array('c', '0', 'Trees are good!'),
    array('d', 'b', 'That is like; your opinion man.'),
    array('e', 'c', 'Teas are good')
);

function rowsToTree($rows)
{
    $tree = array();
    $index = array(); // node id => row id

    // Build an index
    foreach($rows as $id=>&$node) {
        $index[$node[0]] = $id;
    }

    foreach ($rows as $id=>&$node)
    {
        if (!$node[1]) // No parent
        {
            $tree[] = &$node;
        }
        else // Has parent, add this as a child to parent
       {
            $parentKey = $index[$node[1]];
            $rows[$parentKey]['kids'][$id] = &$node;
        }
    }

    return $tree;
}

$data = $commentRows;

// Uncomment to emulate an SQL limit
// $chunks = array_chunk($commentData, 2);
// $data = $chunks[0];

var_dump(rowsToTree($data));