Gali maždaug šitaip, jeigu nenori naudot rekursijos duombazės lygyje (čia naudoju native mysql, geriau naudot kokį wrapperį):
<?php
$construct_tree = function(&$result, $cats, $relations_cats, $ids, $depth) use (&$construct_tree) {
if (is_array($ids) && count($ids) > 0):
// iteruojam per visus paduotus id (tariamai vaikinius ID einamojo elemento)
foreach($ids as $id):
if (!isset($cats[$id])) {
$result = array();
continue;
}
$current_cat = $cats[$id]; // randam einamaja kategorija
// uzsetinam einamosios kategorijos duomenis i rezultatu masyva
$result['id'] = $current_cat['id'];
$result['name'] = $current_cat['name'];
$result['depth'] = $depth;
$result['children'] = array();
if (isset($relations_cats[$id])): // jeigu einamasis elementas turi vaiku - iskvieciam patys save,
// tuos pacius veiksmus padarom kiekvienam is vaiku
$children = $cats[$id];
$construct_tree($result['children'], $cats, $relations_cats, $children, $depth+1);
endif;
endforeach;
endif;
};
$result = mysql_query("SELECT id, parent_id, name, level FROM categories");
// suvaliduoji $result
$cats = array(); // masyvas, kuriame saugomos kategorijos. Raktas - kategorijos ID
$relations_cats = array(); // cia saugosim pseudo hierarchine struktura, kur elemento raktas - tevinis ID, o elementas - pats kategorijos ID
while ($row = mysql_fetch_assoc($result)):
$cats[$row['id']] = $row;
$relations_cats[$row['parent_id']][] = $row['id'];
endwhile;
$kategoriju_struktura = array();
$construct_tree($kategoriju_struktura, $cats, $relations_cats, array(0), 0); // pradedam nuo 0 tevo (nuo elementu, neturinciu tevo)
print_r($kategoriju_struktura);
/*
Array(
0 => Array(
'id' => 1,
'name' => 'Super kategorija 1',
'depth' => 0,
'children' => Array(
0 => Array (
'id' => 3,
'name' => 'Subkategorija 2',
'depth' => 1,
'children' => Array( )
),
1 => Array (
'id' => 4,
'name' => 'Subkategorija 3',
'depth' => 1,
'children' => Array( )
)
)
),
1 => Array(
'id' => 5,
'name' => 'Super kategorija 2',
'depth' => 0,
'children' => Array( )
)
)
*/
print json_encode($kategoriju_struktura); // isvedam json'a
?>
Gal iš pradžių bus sunku kodą suprast, bet pasigilink. Klausk, jeigu kažkas tiksliai neaišku.