PHP从具有关系数据的数组中创build一个multidimensional array

可能重复:
根据父ID值将数组从一个转换为多维

我正在使用PHP。

我有以下数组有关系数据(父子关系)。

Array ( [5273] => Array ( [id] => 5273 [name] => John Doe [parent] => ) [6032] => Array ( [id] => 6032 [name] => Sally Smith [parent] => 5273 ) [6034] => Array ( [id] => 6034 [name] => Mike Jones [parent] => 6032 ) [6035] => Array ( [id] => 6035 [name] => Jason Williams [parent] => 6034 ) [6036] => Array ( [id] => 6036 [name] => Sara Johnson [parent] => 5273 ) [6037] => Array ( [id] => 6037 [name] => Dave Wilson [parent] => 5273 ) [6038] => Array ( [id] => 6038 [name] => Amy Martin [parent] => 6037 ) ) 

我需要它在这个JSON格式:

 { "id":"5273", "name":"John Doe", "data":{ }, "children":[ { "id":" Sally Smith", "name":"6032", "data":{ }, "children":[ { "id":"6034", "name":"Mike Jones", "data":{ }, "children":[ { "id":"6035", "name":"Jason Williams", "data":{ }, "children":[ { "id":"node46", "name":"4.6", "data":{ }, "children":[ ] } ] } ] }, { "id":"6036", "name":"Sara Johnson", "data":{ }, "children":[ ] }, { "id":"6037", "name":"Dave Wilson", "data":{ }, "children":[ { "id":"6038", "name":"Amy Martin", "data":{ }, "children":[ ] } ] } ] } ] } 

我知道我需要创build一个multidimensional array,并通过json_encode()运行它。 我也相信用来做这个的方法需要recursion,因为现实世界的数据可能有一个未知数量的层次。

我会很高兴地展示一些我的方法,但他们没有工作。

任何人都可以帮我吗?

我被要求分享我的工作。 这是我的尝试,但我没有得到这个接近,我不知道它是多么有帮助。

我做了一系列的关系。

 foreach($array as $k => $v){ $relationships[$v['id']] = $v['parent']; } 

我认为(基于另一个SOpost)使用这个关系数据来创build一个新的multidimensional array。 如果我得到这个工作,我会去添加正确的“儿童”标签等。

 $childrenTable = array(); $data = array(); foreach ($relationships as $n => $p) { //parent was not seen before, put on root if (!array_key_exists($p, $childrenTable)) { $childrenTable[$p] = array(); $data[$p] = &$childrenTable[$p]; } //child was not seen before if (!array_key_exists($n, $childrenTable)) { $childrenTable[$n] = array(); } //root node has a parent after all, relocate if (array_key_exists($n, $data)) { unset($data[$n]); } $childrenTable[$p][$n] = &$childrenTable[$n]; } unset($childrenTable); print_r($data); 
 <?php header('Content-Type: application/json; charset="utf-8"'); /** * Helper function * * @param array $d flat data, implementing a id/parent id (adjacency list) structure * @param mixed $r root id, node to return * @param string $pk parent id index * @param string $k id index * @param string $c children index * @return array */ function makeRecursive($d, $r = 0, $pk = 'parent', $k = 'id', $c = 'children') { $m = array(); foreach ($d as $e) { isset($m[$e[$pk]]) ?: $m[$e[$pk]] = array(); isset($m[$e[$k]]) ?: $m[$e[$k]] = array(); $m[$e[$pk]][] = array_merge($e, array($c => &$m[$e[$k]])); } return $m[$r][0]; // remove [0] if there could be more than one root nodes } echo json_encode(makeRecursive(array( array('id' => 5273, 'parent' => 0, 'name' => 'John Doe'), array('id' => 6032, 'parent' => 5273, 'name' => 'Sally Smith'), array('id' => 6034, 'parent' => 6032, 'name' => 'Mike Jones'), array('id' => 6035, 'parent' => 6034, 'name' => 'Jason Williams'), array('id' => 6036, 'parent' => 5273, 'name' => 'Sara Johnson'), array('id' => 6037, 'parent' => 5273, 'name' => 'Dave Wilson'), array('id' => 6038, 'parent' => 6037, 'name' => 'Amy Martin'), ))); 

演示: https : //3v4l.org/s2PNC

好吧,这就是它的工作方式,你开始的时候实际上并不是太遥远,但是你真正需要的是参考。 这是一个通用程序:

由于父节点和子节点之间存在ID关系,因此首先需要根据ID对数据进行索引。 我在这里用一个数组( $rows )来模拟你的数据访问,如果你从数据库中读取,它会是类似的。 有了这个索引,你还可以添加其他属性,比如你的空数据:

 // create an index on id $index = array(); foreach($rows as $row) { $row['data'] = (object) array(); $index[$row['id']] = $row; } 

所以现在所有的条目都在他们的ID上索引。 这是第一步。

第二步同样简单。 因为我们现在可以根据$index的ID访问每个节点,所以我们可以将子节点分配给父节点。

有一个“虚拟”节点,即ID为0的节点。它不存在于任何行中,但是,如果我们也可以添加子节点,则可以使用此子集合作为所有根节点的存储在你的情况下,有一个根节点。

当然,对于ID 0 ,我们不应该处理父母 – 因为它不存在。

所以让我们来做。 我们在这里使用引用,否则相同的节点不能同时为父节点和小节点:

 // build the tree foreach($index as $id => &$row) { if ($id === 0) continue; $parent = $row['parent']; $index[$parent]['children'][] = &$row; } unset($row); 

因为我们使用引用,所以最后一行注意在循环之后取消存储在$row的引用。

现在所有的孩子都被分配给了父母。 这可能已经是,但是不要忘记最后一步,输出的实际节点应该被访问。

为了简洁,只需将根节点分配给$index本身。 如果我们记得,我们想要的唯一根节点是ID为0的节点中的子节点数组中的第一个节点:

 // obtain root node $index = $index[0]['children'][0]; 

就是这样。 我们现在可以立即使用它来生成JSON:

 // output json header('Content-Type: application/json'); echo json_encode($index); 

最后整个代码一目了然:

 <?php /** * @link http://stackoverflow.com/questions/11239652/php-create-a-multidimensional-array-from-an-array-with-relational-data */ $rows = array( array('id' => 5273, 'parent' => 0, 'name' => 'John Doe'), array('id' => 6032, 'parent' => 5273, 'name' => 'Sally Smith'), array('id' => 6034, 'parent' => 6032, 'name' => 'Mike Jones'), array('id' => 6035, 'parent' => 6034, 'name' => 'Jason Williams'), array('id' => 6036, 'parent' => 5273, 'name' => 'Sara Johnson'), array('id' => 6037, 'parent' => 5273, 'name' => 'Dave Wilson'), array('id' => 6038, 'parent' => 6037, 'name' => 'Amy Martin'), ); // create an index on id $index = array(); foreach($rows as $row) { $row['data'] = (object) []; $index[$row['id']] = $row; } // build the tree foreach($index as $id => &$row) { if ($id === 0) continue; $parent = $row['parent']; $index[$parent]['children'][] = &$row; } unset($row); // obtain root node $index = $index[0]['children'][0]; // output json header('Content-Type: application/json'); echo json_encode($index, JSON_PRETTY_PRINT); 

哪个会创build下面的json(这里是PHP 5.4的' JSON_PRETTY_PRINT ):

 { "id": 5273, "parent": 0, "name": "John Doe", "data": { }, "children": [ { "id": 6032, "parent": 5273, "name": "Sally Smith", "data": { }, "children": [ { "id": 6034, "parent": 6032, "name": "Mike Jones", "data": { }, "children": [ { "id": 6035, "parent": 6034, "name": "Jason Williams", "data": { } } ] } ] }, { "id": 6036, "parent": 5273, "name": "Sara Johnson", "data": { } }, { "id": 6037, "parent": 5273, "name": "Dave Wilson", "data": { }, "children": [ { "id": 6038, "parent": 6037, "name": "Amy Martin", "data": { } } ] } ] } 

下面的代码将完成这项工作..你可能需要调整一下根据你的需求。

 $data = array( '5273' => array( 'id' =>5273, 'name'=> 'John Doe', 'parent'=>''), '6032' => array( 'id' =>6032, 'name'=> 'Sally Smith', 'parent'=>'5273'), '6034' => array( 'id' =>6034, 'name'=> 'Mike Jones ', 'parent'=>'6032'), '6035' => array( 'id' =>6035, 'name'=> 'Jason Williams', 'parent'=>'6034') ); $fdata = array(); function ConvertToMulti($data) { global $fdata; foreach($data as $k => $v) { if(empty($v['parent'])){ unset($v['parent']); $v['data'] = array(); $v['children'] = array(); $fdata[] = $v; } else { findParentAndInsert($v, $fdata); } } } function findParentAndInsert($idata, &$ldata) { foreach ($ldata as $k=>$v) { if($ldata[$k]['id'] == $idata['parent']) { unset($idata['parent']); $idata['data'] = array(); $idata['children'] = array(); $ldata[$k]['children'][] = $idata; return; } else if(!empty($v['children'])) findParentAndInsert($idata, $ldata[$k]['children']); } } print_r($data); ConvertToMulti($data); echo "AFTER\n"; print_r($fdata); 

http://codepad.viper-7.com/Q5Buaz