Nested array. Third level is disappearing

Solution 1:

To solve your problem you need to properly understand how variable referencing/aliasing in PHP works.

Look at the following example code, which does not look much different to yours but makes use of references in order to access any parent even it has already "moved":

# 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 now contains all values from $flat - but reordered. Demo.

Solution 2:

Are you sure that output array is correct? Surely the key 2 should be a child of 1 (since 2 has 'parent'=>1)? If this is not the case, I don't understand what are actually trying to do and how the keys all relate to each other.

If 2 should be a child of 1, this works:

$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);