我想要一个像这样的评论表
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";
我不是真的在寻找所有这些的代码,只是一个伪代码解决方案。
答案 0 :(得分:1)
当您使用Adjacency列表尝试检索层次结构中的所有子节点时,会出现此问题。如果你使用的是mysql,它就不能很好地处理递归。 (甲骨文是另一回事)。
创建结构很简单,你不应该真正关心如何创建数组结构,首先你要尝试创建一个有效的查询和高效的模型,完美地发挥你将要查询的类型制造。
例如,您说要检索所有子节点。那么你应该使用nested set models
代替adjacency list
或lft
。
看一下这些资源......
Is there a simple way to query the children of a node?
嵌套集的想法是,存储节点的right
和lft
边缘值,这意味着检索任何子节点非常简单,因为您只需选择有节点的节点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 循环。
此代码将按照您想要的方式创建一棵树,以及未确定的深度和子项数。
使用引用,我们可以假设所有内容都保存在数组 $ 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)
);