Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中将此MPTT数组转换为树结构?_Php_Arrays_Tree_Mptt - Fatal编程技术网

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

如何在PHP中将此MPTT数组转换为树结构?,php,arrays,tree,mptt,Php,Arrays,Tree,Mptt,我在数据库中有分层数据,按格式存储。我在一个查询中提取数据,该查询类似于“按左;”从表顺序中选择ID、左、右、名称等”。我试图将DB提供的平面数组中的数据转换为树结构,然后使用PHP的JSON_encode函数将其输出为JSON 不过,我很难让我的树结构代码在第一级之外工作。下面是一个最低测试用例: 正如您所看到的,尽管projectListToTree函数中的输出似乎表明它应该在那里,但“孙子”正在丢失。好像我扔给它的任何树结构都会把第二层以下的东西掉下来。对可能发生的事情有什么见解吗 谢谢

我在数据库中有分层数据,按格式存储。我在一个查询中提取数据,该查询类似于“按
;”从表顺序中选择ID、
、名称等”。我试图将DB提供的平面数组中的数据转换为树结构,然后使用PHP的JSON_encode函数将其输出为JSON

不过,我很难让我的树结构代码在第一级之外工作。下面是一个最低测试用例:

正如您所看到的,尽管projectListToTree函数中的输出似乎表明它应该在那里,但“孙子”正在丢失。好像我扔给它的任何树结构都会把第二层以下的东西掉下来。对可能发生的事情有什么见解吗


谢谢

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

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

功能项目列表目录($projects){
$stack=Array();
对于($x=0;$x0&&$stack[count($stack)-1]['Right']<$project['Right']{
数组_pop($stack);
}
如果(计数($stack)>0){
$stack[count($stack)-1]['Children'][]=&$project;
echo“将“$project['Name']”添加到“$stack[count($stack)-1]['Name']”中,总共
.count($stack[count($stack)-1]['Children'])“Children\n”;
回音“\n”;
}否则{
回显“无父项\n”;
}
回显“堆栈计数:”.count($stack)。“\n”;
$stack[]=&$project;
}
echo“堆栈中的左侧:”.count($stack)。“\n”;
返回$stack[0];
}
请注意,在三个位置添加了一个符号AND

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


这还意味着,在嵌套阵列中使用大量数据时,处理器使用率和内存占用率会非常高。例如,在上面的示例中,当projectListToTree()返回时,完整的数组树被复制到局部变量$tree中,并且(因为php垃圾回收器吸吮)在内存中存在两次。

您是否在调用array_pop()时放入了echo语句?没有经过测试就阅读了这篇文章,我想你是在把这张唱片从堆栈中弹出并扔掉。

谢谢!我想我仍然习惯于将数组视为对象并通过引用进行赋值的语言。除了关于数组推送($stack,&$project)行的警告(通过引用传递的调用时间已被弃用)之外,这一点工作得非常好,我将其更改为$stack[]=&$project;,从而对其进行了更正;。我更改了答案中的密码以避开警告。
<pre><?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);

?></pre>
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) {
      }
    }
  }
}
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];
}