我正在寻找一个示例,应该如何构造作为RecursiveArrayIterator的参数传递的递归数组。我有一个带id,parent_id和title的mysql表:
id parent_id title
-----------------|-------------------
1 0 | Item 1
2 1 | Item 2
3 1 | Item 3
4 3 | Item 4
5 4 | Item 5
我想从表中创建一个数组,可以传递给RecursiveArrayIterator来构建树,菜单,选项等等。我试过这个“build_tree”函数https://stackoverflow.com/a/8587437/1746522来从mysql表创建一个数组。结果数组看起来像:
array (size=2)
0 =>
array (size=3)
'id' => string '1' (length=1)
'title' => string 'Item 1' (length=6)
'parent_id' => string '0' (length=1)
'children' =>
array (size=2)
0 =>
array (size=3)
...
1 =>
array (size=3)
...
但是当我将结果数组传递给RecursiveArrayIterator时,它看起来很奇怪。例如。使用此功能:
$array = new RecursiveArrayIterator($tree);
$iterater = new RecursiveIteratorIterator($array);
foreach ($iterater as $key => $value) {
$d = $iterater->getDepth();
echo "depth=$d k=$key v=$value\n";
}
我有一些奇怪且无法使用的输出,如:
depth=0 k=0 v=Array
depth=1 k=id v=1
depth=1 k=title v=Item 1
depth=1 k=parent_id v=0
depth=2 k=0 v=Array
depth=3 k=id v=2
depth=3 k=title v=Item 2
depth=3 k=parent_id v=1
depth=4 k=0 v=Array
....
深度是错误的,它遍历单个值而不是元素。传递给RecursiveArrayIterator的数组可能是“格式错误”,应该以其他方式构造吗?
我原本希望看到这样的事情:
depth=0 k=1 v=Array
depth=1 k=2 v=Array
depth=1 k=3 v=Array
其中Array包含节点的所有值,如parent_id和title,k是mysql列id的id。
答案 0 :(得分:2)
默认情况下,RecursiveIteratorIterator
类只会显示树的“叶子”。也就是说,树中不是数组的所有内容。
您希望初始化迭代器以显示数组节点和叶子。然后,您只想为那些阵列的节点打印出数据。
$array = new RecursiveArrayIterator($records);
$iterater = new RecursiveIteratorIterator($array, RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterater as $key => $value) {
if (is_array($value)) {
$d = $iterater->getDepth();
echo "depth=$d k=$key value=$value\n";
}
}
> depth=0 k=0 value=Array
> depth=0 k=1 value=Array
> depth=1 k=children value=Array
> depth=2 k=0 value=Array
> depth=2 k=1 value=Array
此时,您会注意到有一个名为“儿童”的额外图层会影响您的深度计数。发生这种情况是因为节点的后代被放入它们自己的数组中。您可以跳过打印这些行,并发出有关数组中项目的更多数据,如下所示:
foreach ($iterater as $key => $value) {
if (is_array($value) && $key !== 'children') {
$d = $iterater->getDepth();
echo "depth=$d k=$key title={$value['title']}\n";
}
}
答案 1 :(得分:0)
我的最终解决方案,无限深度,只有一个查询,表格中的所有信息以及 RecursiveIteratorIterator 的所有功能,如 children 和 depth 。我在我的解决方案中使用了两个数组。
平面阵列
select * from table
并像往常一样创建平面数组:
$info[1] = array('parent_id' => 0, 'title' => 'Item 1');
$info[2] = array('parent_id' => 1, 'title' => 'Item 2');
$info[3] = array('parent_id' => 1, 'title' => 'Item 3');
$info[4] = array('parent_id' => 3, 'title' => 'Item 4');
$info[5] = array('parent_id' => 4, 'title' => 'Item 5');
使用 id 列作为数组索引。
嵌套数组
从 $ info 创建包含项目的唯一ID的嵌套数组:
function tree_structure($info, $parent = 0) {
foreach ($info as $row) {
if ($row['parent_id'] == $parent)
$struc[$row['id']] = tree_structure($info, $row['id']);
}
return $struc;
}
此数组可以传递给RecursiveArrayIterator。
现在有两个阵列:
RecursiveArrayIterator
开始使用RecursiveArrayIterator
$array = new RecursiveArrayIterator($struc);
$iterator = new RecursiveIteratorIterator($array, TRUE);
$iterator->rewind();
while ($iterator->valid()) {
// Get the id
$iterator->key();
// Get the depth
$iterator->getDepth();
// Check if it has children
$iterator->hasChildren();
// Get the number of children
sizeof($iterator->callGetChildren());
// Get all information for the node from the flat array
$info[$iterator->key()];
$iterator->next();
}
代码中的行 $ info [$ iterator-> key()] 执行实际操作。使用此行,您可以获得有关节点的所有信息,而不会弄乱结构。