您可以一次获取所有类别。
假设您有一个来自数据库的平面结果,如下所示:
$categories = array(
array('id' => 1, 'parent' => 0, 'name' => 'Category A'),
array('id' => 2, 'parent' => 0, 'name' => 'Category B'),
array('id' => 3, 'parent' => 0, 'name' => 'Category C'),
array('id' => 4, 'parent' => 0, 'name' => 'Category D'),
array('id' => 5, 'parent' => 0, 'name' => 'Category E'),
array('id' => 6, 'parent' => 2, 'name' => 'Subcategory F'),
array('id' => 7, 'parent' => 2, 'name' => 'Subcategory G'),
array('id' => 8, 'parent' => 3, 'name' => 'Subcategory H'),
array('id' => 9, 'parent' => 4, 'name' => 'Subcategory I'),
array('id' => 10, 'parent' => 9, 'name' => 'Subcategory J'),
);
您可以创建一个简单的函数,将该平面列表转换为结构,最好是在函数内部。我使用逐引用传递,以便每个类别只有一个数组,而不是一个类别的数组的多个副本。
function categoriesToTree(&$categories) {
地图用于快速查找类别。在这里,我还为“根”级别创建了一个虚拟数组。
$map = array(
0 => array('subcategories' => array())
);
我向每个类别数组添加了另一个字段(子类别),并将其添加到地图中。
foreach ($categories as &$category) {
$category['subcategories'] = array();
$map[$category['id']] = &$category;
}
再次遍历每个类别,将自身添加到其父类别的子类别列表中。此处的引用很重要,否则当有更多子类别时,不会更新已添加的类别。
foreach ($categories as &$category) {
$map[$category['parent']]['subcategories'][] = &$category;
}
最后,返回该虚拟类别的子类别,这些子类别引用所有顶级categories._
return $map[0]['subcategories'];
}
用法:
$tree = categoriesToTree($categories);
这是Codepad上正在运行的代码。