function buildTree(array $flat, $pidKey = 'pid', $idKey = 'id', $childrenKey = 'children') {
$grouped = [];
foreach ($flat as $sub) {
$grouped[$sub[$pidKey]][] = $sub;
}
$fnBuilder = function(&$siblings) use ($grouped, $idKey, $childrenKey, &$fnBuilder) {
foreach ($siblings as &$sibling) {
$id = $sibling[$idKey];
if (isset($grouped[$id])) {
$sibling[$childrenKey] = $grouped[$id];
$fnBuilder($sibling[$childrenKey]);
}
}
};
$tree = [];
if (isset($grouped[0])) {
$tree = $grouped[0];
$fnBuilder($tree);
}
return $tree;
}