PHP:构建分层数组结构

PHP:构建分层数组结构,php,json,hierarchy,Php,Json,Hierarchy,我在构建分层数组结构时遇到了一些问题-我几乎已经完成了,但是有一些无法解释的原因使我的数组看起来很奇怪,我希望您能帮助我 树形结构为: root |data |-children |--data |--children |---data |---children 任何孩子都可以有任意数量的孩子,每个孩子都可以有任意数量的父母 我有一个构建树的函数: private function build_tree($rows,$parent) { $i = 0; $response -&

我在构建分层数组结构时遇到了一些问题-我几乎已经完成了,但是有一些无法解释的原因使我的数组看起来很奇怪,我希望您能帮助我

树形结构为:

root
|data
|-children
|--data
|--children
|---data
|---children
任何孩子都可以有任意数量的孩子,每个孩子都可以有任意数量的父母

我有一个构建树的函数:

private function build_tree($rows,$parent) {
    $i = 0;
    $response -> result = array();
    $result = array();
    $leaf = false;

    foreach($rows as $row) {
        if($row['parent_id'] == $parent) {
            $leaf = is_null($row['treeDef']) ? false : true;
            $workingSet = array_merge($result,array(                
                'id' => (int)$i, 
                'parent_id' => (int)$row['parent_id'], 
                'child_id' => (int)$row['id'], 
                'name' => (string)$row['resourceName'], 
                'updated' => strtotime($row['updated']), 
                'purchasedUnit' => (string)$row['purchasingUnit'], 
                'purchasedCost' => (double)$row['purchasingCosts'], 
                'purchasedDiscount' => (double)$row['discount'], 
                'estimateUnit' => (string)$row['estimatingUnit'], 
                'profitAddOn' => (string)$row['profitAddOn'], 
                'landedCost' => (double)$row['landedCost'], 
                'unitCorrelation' => (double)$row['unitCorrelation'], 
                'leadTime' => (string)$row['leadTime'], 
                'ResourceClassShortname' => (string)$row['ResourceClassShortname'], 
                'supplierName' => (string)$row['nameSupplier'],
                'iconCls' => (string)$row['typeIcon'],
                'leaf' => $leaf
            ));
            $hasChildren = $this->Resource_model->has_children($rows,$row['id']);
            if ($hasChildren->check) {
                if (!$leaf) {
                    for($j=0; $j <= ($hasChildren -> rows); $j++) {
                        $parentArray = $workingSet;
                        $childArray = $this -> Resource_model -> build_tree($rows,$row['id']);
                        $workingSet = array_merge($parentArray,array('children' => $childArray -> result));
                    }
                } 
            }
            $result[$i] = $workingSet;
            $i++;
        }
    }

    $response -> result = $result;
    $response -> rows = $i; 
    return $response;
}
私有函数构建树($rows,$parent){
$i=0;
$response->result=array();
$result=array();
$leaf=false;
foreach($行作为$行){
if($row['parent\u id']==$parent){
$leaf=is_null($row['treeDef'])?false:true;
$workingSet=array\u merge($result,array(
'id'=>(int)$i,
'parent_id'=>(int)$row['parent_id'],
'child_id'=>(int)$row['id'],
'name'=>(字符串)$row['resourceName'],
'updated'=>strotime($row['updated']),
'purchasedUnit'=>(字符串)$row['PurchaseInUnit'],
'purchasedCost'=>(双倍)$row['PurchasedCosts'],
'purchasedDiscount'=>(双倍)$row['折扣'],
'estimateUnit'=>(字符串)$row['estimatingUnit'],
'profitAddOn'=>(字符串)$row['profitAddOn'],
“landedCost”=>(双倍)$row['landedCost'],
'unitCorrelation'=>(双精度)$row['unitCorrelation'],
“交付周期”=>(字符串)$row['leadTime'],
'ResourceClassShortname'=>(字符串)$row['ResourceClassShortname'],
“供应商名称”=>(字符串)$row[“名称供应商”],
'iconCls'=>(字符串)$row['typeIcon'],
'leaf'=>$leaf
));
$haschilds=$this->Resource_model->has_children($rows,$row['id');
如果($hasChildren->check){
如果(!$leaf){
对于($j=0;$j行);$j++){
$parentArray=$workingSet;
$childArray=$this->Resource_model->build_tree($rows,$row['id');
$workingSet=array\u merge($parentArray,array('children'=>$childArray->result));
}
} 
}
$result[$i]=$workingSet;
$i++;
}
}
$response->result=$result;
$response->rows=$i;
返回$response;
}
这将生成以下JSON:

每个有2个子项(或更多子项?——没有测试值)的项目都会得到第一个项目,但第二个项目也包含第一个项目——复制所有结果


非常感谢您的帮助。

使用
array\u push
而不是
array\u merge
-这将添加
子数组,而不是尝试将其与现有子数组合并

在代码的这一部分(已编辑):

$haschilds=$this->Resource_model->has_children($rows,$row['id');
如果($hasChildren->check){
如果(!$leaf){
对于($j=0;$j行);$j++){
$parentArray=$workingSet;
$childArray=$this->Resource_model->build_tree($rows,$row['id');
$workingSet=array\u push($parentArray,array('children'=>$childArray->result));
}
} 
}

而不是
array\u merge
使用
array\u push
-这将添加
子数组,而不是尝试将其与现有子数组合并

在代码的这一部分(已编辑):

$haschilds=$this->Resource_model->has_children($rows,$row['id');
如果($hasChildren->check){
如果(!$leaf){
对于($j=0;$j行);$j++){
$parentArray=$workingSet;
$childArray=$this->Resource_model->build_tree($rows,$row['id');
$workingSet=array\u push($parentArray,array('children'=>$childArray->result));
}
} 
}

成功了,下面是最后的代码:

private function build_tree($rows,$parent) {
    $i = 0;
    $response -> result = array();
    $result = array();
    $leaf = false;
    $newArray = array();

    foreach($rows as $row) {
        if($row['parent_id'] == $parent) {
            $leaf = is_null($row['treeDef']) ? false : true;
            $newArray = array(              
                'id' => (int)$i, 
                'parent_id' => (int)$row['parent_id'], 
                'child_id' => (int)$row['id'], 
                'name' => (string)$row['resourceName'], 
                'updated' => strtotime($row['updated']), 
                'purchasedUnit' => (string)$row['purchasingUnit'], 
                'purchasedCost' => (double)$row['purchasingCosts'], 
                'purchasedDiscount' => (double)$row['discount'], 
                'estimateUnit' => (string)$row['estimatingUnit'], 
                'profitAddOn' => (string)$row['profitAddOn'], 
                'landedCost' => (double)$row['landedCost'], 
                'unitCorrelation' => (double)$row['unitCorrelation'], 
                'leadTime' => (string)$row['leadTime'], 
                'ResourceClassShortname' => (string)$row['ResourceClassShortname'], 
                'supplierName' => (string)$row['nameSupplier'],
                'iconCls' => (string)$row['typeIcon'],
                'leaf' => $leaf
            );

            $hasChildren = $this -> Resource_model -> has_children($rows,$row['id']);
            if ($hasChildren->check) {
                for($j=0; $j <= ($hasChildren -> rows); $j++) {
                    $childArray = $this -> Resource_model -> build_tree($rows,$row['id']);
                    $newArray = array_merge($newArray, array('children' => $childArray -> result));
                }
            }
            $result[$i] = $newArray;
            $i++;
        }
    }

    $response -> result = $result;
    $response -> rows = $i; 
    return $response;
}
私有函数构建树($rows,$parent){
$i=0;
$response->result=array();
$result=array();
$leaf=false;
$newArray=array();
foreach($行作为$行){
if($row['parent\u id']==$parent){
$leaf=is_null($row['treeDef'])?false:true;
$newArray=数组(
'id'=>(int)$i,
'parent_id'=>(int)$row['parent_id'],
'child_id'=>(int)$row['id'],
'name'=>(字符串)$row['resourceName'],
'updated'=>strotime($row['updated']),
'purchasedUnit'=>(字符串)$row['PurchaseInUnit'],
'purchasedCost'=>(双倍)$row['PurchasedCosts'],
'purchasedDiscount'=>(双倍)$row['折扣'],
'estimateUnit'=>(字符串)$row['estimatingUnit'],
'profitAddOn'=>(字符串)$row['profitAddOn'],
“landedCost”=>(双倍)$row['landedCost'],
'unitCorrelation'=>(双精度)$row['unitCorrelation'],
“交付周期”=>(字符串)$row['leadTime'],
'ResourceClassShortname'=>(字符串)$row['ResourceClassShortname'],
“供应商名称”=>(字符串)$row[“名称供应商”],
'iconCls'=>(字符串)$row['typeIcon'],
'leaf'=>$leaf
);
$haschilds=$this->Resource_model->has_children($rows,$row['id');
如果($hasChildren->check){
对于($j=0;$j行);$j++){
$childArray=$this->Resource_model->build_tree($rows,$row['id');
$newArray=array\u merge($newArray,array('children'=>$childArray->result));
}
}
$result[$i]=$newArray;
private function build_tree($rows,$parent) {
    $i = 0;
    $response -> result = array();
    $result = array();
    $leaf = false;
    $newArray = array();

    foreach($rows as $row) {
        if($row['parent_id'] == $parent) {
            $leaf = is_null($row['treeDef']) ? false : true;
            $newArray = array(              
                'id' => (int)$i, 
                'parent_id' => (int)$row['parent_id'], 
                'child_id' => (int)$row['id'], 
                'name' => (string)$row['resourceName'], 
                'updated' => strtotime($row['updated']), 
                'purchasedUnit' => (string)$row['purchasingUnit'], 
                'purchasedCost' => (double)$row['purchasingCosts'], 
                'purchasedDiscount' => (double)$row['discount'], 
                'estimateUnit' => (string)$row['estimatingUnit'], 
                'profitAddOn' => (string)$row['profitAddOn'], 
                'landedCost' => (double)$row['landedCost'], 
                'unitCorrelation' => (double)$row['unitCorrelation'], 
                'leadTime' => (string)$row['leadTime'], 
                'ResourceClassShortname' => (string)$row['ResourceClassShortname'], 
                'supplierName' => (string)$row['nameSupplier'],
                'iconCls' => (string)$row['typeIcon'],
                'leaf' => $leaf
            );

            $hasChildren = $this -> Resource_model -> has_children($rows,$row['id']);
            if ($hasChildren->check) {
                for($j=0; $j <= ($hasChildren -> rows); $j++) {
                    $childArray = $this -> Resource_model -> build_tree($rows,$row['id']);
                    $newArray = array_merge($newArray, array('children' => $childArray -> result));
                }
            }
            $result[$i] = $newArray;
            $i++;
        }
    }

    $response -> result = $result;
    $response -> rows = $i; 
    return $response;
}