检索子对象

时间:2011-09-02 13:58:48

标签: php multidimensional-array

我想要一个像这样的评论表

id | comment | parent_id
--------------------------
1    text1        0
2    text2        1
3    text3        2
4    text4        3
5    text5        3
6    text6        5

我想构建一个显示父母和孩子的层次结构的数组。树应该回到不确定的世代。我不想使用嵌套的foreach循环,因为我不确定它有多深。这就是为什么我在这里,我不确定这样的问题的最佳实践。我还想在数组中显示深度。以下是一个例子。它与上面的表格没有关系,但希望能让你知道我需要什么。

array(
    "depth"=> 4
    "parent" => array(
        "id"=> 1,
        "comment" => "sometext1"
        "child_count" => 2,
        "children" => array(
            0 => array(
                "id" => 2
                "comment" => "sometext2",
                "child_count" => 0,
                "children" => null
            ),
            1 => array(
                "id" => 3
                "comment" => "sometext3"
                "child_count" => 1,
                "children" => array(
                    0 => array(
                        "id" => 2
                        "comment" => "sometext2",
                        "child_count" => 2,
                        "children" => array(
                            0 => array(
                                "id" => 2
                                "comment" => "sometext2",
                                "child_count" => 0,
                                "children" => null
                            ),
                            1 => array(
                                "id" => 2
                                "comment" => "sometext2",
                                "child_count" => 1,
                                "children" => array(
                                    "id" => 2
                                    "comment" => "sometext2",
                                    "child_count" => 0,
                                    "children" => null
                                )
                            )
                    )
                )
            )
        )
    )
)

我打算使用foreach并做一个SQL语句来检索那些父母/孩子的孩子。即

$sql = "SELECT * FROM comments WHERE parent = $parent_id";

我不是真的在寻找所有这些的代码,只是一个伪代码解决方案。

2 个答案:

答案 0 :(得分:1)

当您使用Adjacency列表尝试检索层次结构中的所有子节点时,会出现此问题。如果你使用的是mysql,它就不能很好地处理递归。 (甲骨文是另一回事)。

创建结构很简单,你不应该真正关心如何创建数组结构,首先你要尝试创建一个有效的查询和高效的模型,完美地发挥你将要查询的类型制造。

例如,您说要检索所有子节点。那么你应该使用nested set models代替adjacency listlft

看一下这些资源......

Is there a simple way to query the children of a node?

嵌套集的想法是,存储节点的rightlft边缘值,这意味着检索任何子节点非常简单,因为您只需选择有节点的节点lft值大于目标节点rgt的值,并且小于id | comment | parent_id | lft | rgt | ------------------------------------------------- 1 World null 1 12 2 Europe 1 2 11 3 England 2 3 10 4 Kent 3 4 5 5 Devon 3 6 9 6 Plymouth 5 7 8 值。

检索结果集后,创建阵列结构将毫不费力。

见这里:http://en.wikipedia.org/wiki/Nested_set_model

一旦你得到了你的结果,那么看一下这个问题,我在大约一年前问过这个问题,这正是你想要的。 PHP > Form a multi-dimensional array from a nested set model flat array

实施例

{{1}}

答案 1 :(得分:1)

这可以在PHP中轻松完成 ...为此,您需要两个数组和两个 while 循环。

此代码将按照您想要的方式创建一棵树,以及未确定的深度和子项数。

Pastebin to the working code.

使用引用,我们可以假设所有内容都保存在数组 $ data 中,结构如下:(id, comment, parent_id)其中 parent_id 指向 id

构建树的代码。

$tree = array();
reset($data);
while (list($k, $v) = each($data))
    if (0 == ($pid = $v['parent_id']))
        $tree[$k] =& $data[$k]; else
        $data[$pid]['children'][$k] =& $data[$k];

并生成深度和子计数。

reset($data);
while (list($k, $v) = each($data))
    if (0 != $v['parent_id'])
    {
        $ref =& $data[$k];
        $depth = 0;
        do
        {
            if ($depth) $ref =& $data[$ref['parent_id']];
            $dre =& $ref['depth'];
            if (!isset($dre) || $dre <= $depth) $dre =  $depth++;
            if (isset($ref['children']))
                $ref['child_count'] = count($ref['children']);
                else
            {   
                $ref['child_count'] = 0;
                $ref['children'] = null;
            }   
        }   
        while ($ref['parent_id']);
    }

我的所有代码都是动态编写的,甚至没有经过测试,所以如果有任何错误请原谅meeeeeeeee !!!!!!!!!!! ←忘记了,我试过了它,解决了几个问题,现在运作得很好。

注意

要使此代码生效,每个项目的索引必须等于其ID。

我用来尝试代码的数组。

$data = array(
    '1' => array('id' => '1', 'comment' => 'a', 'parent_id' => 0),
    '2' => array('id' => '2', 'comment' => 'b', 'parent_id' => 0),
    '3' => array('id' => '3', 'comment' => 'c', 'parent_id' => 1),
    '4' => array('id' => '4', 'comment' => 'd', 'parent_id' => 1),
    '5' => array('id' => '5', 'comment' => 'e', 'parent_id' => 2),
    '6' => array('id' => '6', 'comment' => 'f', 'parent_id' => 2),
    '7' => array('id' => '7', 'comment' => 'g', 'parent_id' => 5),
    '8' => array('id' => '8', 'comment' => 'h', 'parent_id' => 7)
    );