数组转换成树php,如何在PHP中将此MPTT数组转换为树结构?

本文介绍如何在PHP中处理Modified Preorder Tree Traversal (MPTT)格式的数据,从分层数据库查询结果转换为树形结构,并解决数组引用问题导致的层级丢失。作者分享了解决方案,包括使用引用分配而非复制,以确保树状结构完整显示所有层级。
摘要由CSDN通过智能技术生成

我在数据库中有分层数据,以Modified Preorder Tree Traversal格式存储.我在一个看起来类似“SELECT ID,Left,Right,Name等FROM FROM ORDER BY Left;”的查询中提取数据.我试图将这个数据从一个平面数组转换成DB给我一个树结构,然后我将用PHP的json_encode函数输出为JSON.

但是,我无法让我的树形结构代码超出第一级.这是一个最小的测试用例:

<?php 

function projectListToTree($projects) {

$stack = Array();

for($x =0; $x < count($projects); $x++) {

$project = $projects[$x];

$project['Children'] = Array();

while(count($stack) > 0 && $stack[count($stack) - 1]['Right'] < $project['Right']) {

array_pop($stack);

}

if(count($stack) > 0) {

$stack[count($stack) - 1]['Children'][] = $project;

echo "Adding " . $project['Name'] . " to " . $stack[count($stack) - 1]['Name'] . " for a total of "

. count($stack[count($stack) - 1]['Children']) . " kids\n";

} else {

echo "No parent\n";

}

echo "stack count: " . count($stack) . "\n";

array_push($stack, $project);

}

echo "Left in stack: " . count($stack) . "\n";

return $stack[0];

}

/*

This is basically what comes from the DB.

Should be:

Parent

First Child

Second Child

Grand Child

*/

$projects = Array(

Array(

"ID" => "2",

"Left" => "2",

"Right" => "9",

"ParentID" => "1",

"Name" => "Parent"

),

Array(

"ID" => "3",

"Left" => "3",

"Right" => "4",

"ParentID" => "2",

"Name" => "First Child"

),

Array(

"ID" => "4",

"Left" => "5",

"Right" => "8",

"ParentID" => "2",

"Name" => "Second Child"

),

Array(

"ID" => "5",

"Left" => "6",

"Right" => "7",

"ParentID" => "4",

"Name" => "Grand Child"

)

);

$tree = projectListToTree($projects);

echo "-----\n\n\n\n";

var_dump($tree);

?>

这就是我得到的输出:

No parent

stack count: 0

Adding First Child to Parent for a total of 1 kids

stack count: 1

Adding Second Child to Parent for a total of 2 kids

stack count: 1

Adding Grand Child to Second Child for a total of 1 kids

stack count: 2

Left in stack: 3

-----

array(6) {

["ID"]=>

string(1) "2"

["Left"]=>

string(1) "2"

["Right"]=>

string(1) "9"

["ParentID"]=>

string(1) "1"

["Name"]=>

string(6) "Parent"

["Children"]=>

array(2) {

[0]=>

array(6) {

["ID"]=>

string(1) "3"

["Left"]=>

string(1) "3"

["Right"]=>

string(1) "4"

["ParentID"]=>

string(1) "2"

["Name"]=>

string(11) "First Child"

["Children"]=>

array(0) {

}

}

[1]=>

array(6) {

["ID"]=>

string(1) "4"

["Left"]=>

string(1) "5"

["Right"]=>

string(1) "8"

["ParentID"]=>

string(1) "2"

["Name"]=>

string(12) "Second Child"

["Children"]=>

array(0) {

}

}

}

}

正如你所看到的,即使projectListToTree函数中的输出似乎表明它应该存在,某个地方“孙子”也会迷路.看起来我抛出的任何树形结构都会降低第二级以下的任何结构.对可能发生的事情的任何见解?

谢谢!

解决方法:

问题是分配数组不会复制引用,而是复制数组.这意味着,您在“父”节点的“子”中拥有的“第二个子”数组与您添加“孙子”的数组不同,而是它的副本.

要解决此问题,您必须显式使用引用分配而不是复制:

function projectListToTree($projects) {

$stack = Array();

for($x =0; $x < count($projects); $x++) {

$project = &$projects[$x];

$project['Children'] = array();

while(count($stack) > 0 && $stack[count($stack) - 1]['Right'] < $project['Right']) {

array_pop($stack);

}

if(count($stack) > 0) {

$stack[count($stack) - 1]['Children'][] = &$project;

echo "Adding " . $project['Name'] . " to " . $stack[count($stack) - 1]['Name'] . " for a total of "

. count($stack[count($stack) - 1]['Children']) . " kids\n";

echo "\n";

} else {

echo "No parent\n";

}

echo "stack count: " . count($stack) . "\n";

$stack[] = &$project;

}

echo "Left in stack: " . count($stack) . "\n";

return $stack[0];

}

请注意,在三个地方添加了&符号.

由于这个问题,在php中使用嵌套数组和赋值运算符时必须非常小心.

这也意味着在嵌套数组中使用大量数据时,处理器使用率和内存占用量很大.例如,在上面的例子中,当projectListToTree()返回时,完整的数组树被复制到局部变量$tree并且(因为php垃圾收集器很糟糕)在内存中两次.

标签:php,arrays,tree,mptt

来源: https://codeday.me/bug/20190701/1344863.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值