Вложенный массив. Третий уровень исчезает

У меня есть этот массив:

$a = array( "7" => array( "id" => 7, "parent" => 6 ), "6" => array( "id" => 6, "parent" => 5 ), "5" => array( "id" => 5, "parent" => 4 ), "4" => array( "id" => 4, "parent" => 0 ), "3" => array( "id" => 7, "parent" => 2 ), "2" => array( "id" => 7, "parent" => 1 ), "1" => array( "id" => 7, "parent" => 0 ) ); 

в результате я хочу, чтобы:

 $a = array( "4" => array( "id" => 4, "parent" => 0, array( "5" => array( "id" => 5, "parent" => 4, array( "6" => array( "id" => 6, "parent" => 5, array( "7" => array( "id" => 7, "parent" => 6 ) ) ) ) ) ) ), "2" => array( "id" => 7, "parent" => 1, array( "3" => array( "id" => 7, "parent" => 2 ) ) ), "1" => array( "id" => 7, "parent" => 0 ) ); 

код, который я использую:

 foreach($a as $v) { if(isset($a[$v['PARENT']])) { $a[$v['PARENT']][$v['ID']] = $v; unset($a[$v['ID']]); } } с foreach($a as $v) { if(isset($a[$v['PARENT']])) { $a[$v['PARENT']][$v['ID']] = $v; unset($a[$v['ID']]); } } 

и проблема в том, что я получаю этот результат:

 $a = array( "4" => array( "id" => 4, "parent" => 0, array( "5" => array( "id" => 5, "parent" => 4 ) ) ), "2" => array( "id" => 7, "parent" => 1, array( "3" => array( "id" => 7, "parent" => 2 ) ) ), "1" => array( "id" => 7, "parent" => 0 ) ); 

вместо необходимости.

Чтобы решить вашу проблему, вам необходимо правильно понять, как работает ссылка refering / aliasing в PHP .

Посмотрите на следующий пример кода, который не сильно отличается от вашего, но использует ссылки для доступа к любому родителю, даже если он уже «перемещен»:

 # transform $flat into a tree: foreach($flat as $id => &$value) { # check if there is a parent if ($parentId = $value['parent']) { $flat[$parentId][0][$id] =& $value; # add child to parent unset($flat[$id]); # remove reference from topmost level } } unset($value); # remove iterator reference print_r($flat); # your tree с # transform $flat into a tree: foreach($flat as $id => &$value) { # check if there is a parent if ($parentId = $value['parent']) { $flat[$parentId][0][$id] =& $value; # add child to parent unset($flat[$id]); # remove reference from topmost level } } unset($value); # remove iterator reference print_r($flat); # your tree с # transform $flat into a tree: foreach($flat as $id => &$value) { # check if there is a parent if ($parentId = $value['parent']) { $flat[$parentId][0][$id] =& $value; # add child to parent unset($flat[$id]); # remove reference from topmost level } } unset($value); # remove iterator reference print_r($flat); # your tree 

$flat теперь содержит все значения из $flat – но переупорядочено. Демо .

Вы уверены, что выходной массив правильный? Разумеется, ключ 2 должен быть ребенком 1 (поскольку 2 имеет 'parent'=>1 )? Если это не так, я не понимаю, что на самом деле пытается сделать и как все ключи связаны друг с другом.

Если 2 должен быть ребёнком 1 , это работает:

 $keep = array(); foreach ($a as $k => &$v) { // Loop the array first time and create references to // structure the array how you want it if ($v['parent']) { $a[$v['parent']][0] = array($k => &$v); } else $keep[] = $k; } foreach ($a as $k => $v) { // Loop it again to get rid of non-root nodes from the root if (!in_array($k,$keep)) { unset($a[$k]); } } print_r($a); с $keep = array(); foreach ($a as $k => &$v) { // Loop the array first time and create references to // structure the array how you want it if ($v['parent']) { $a[$v['parent']][0] = array($k => &$v); } else $keep[] = $k; } foreach ($a as $k => $v) { // Loop it again to get rid of non-root nodes from the root if (!in_array($k,$keep)) { unset($a[$k]); } } print_r($a);