$data = [
[ 'id' => 1, 'parent_id' => 0, ],
[ 'id' => 2, 'parent_id' => 0, ],
[ 'id' => 3, 'parent_id' => 0, ],
[ 'id' => 4, 'parent_id' => 1, ],
[ 'id' => 5, 'parent_id' => 1, ],
[ 'id' => 6, 'parent_id' => 4, ],
[ 'id' => 7, 'parent_id' => 2, ],
[ 'id' => 8, 'parent_id' => 2, ],
[ 'id' => 9, 'parent_id' => 3, ]
];
$result = [
[
'id' => 1,
'parent_id' => 0,
'children' => [
[
'id' => 4,
'parent_id' => 1,
'children' => [
[
'id' => 6,
'parent_id' => 4,
]
]
],
[
'id' => 5,
'parent_id' => 1,
]
]
],
// ...
];
class AdjacencyList
{
private static $tmpData;
public static function renderUnorderedList($rgData, \Closure $callback)
{
$html = '<ul>';
foreach ($rgData as $item) {
$children = $item['children'];
$item['children'] = !empty($children);
$html .= '<li>';
ob_start();
$callback($item);
$html .= ob_get_clean();
if (!empty($children)) {
$html .= self::renderUnorderedList($children, $callback);
}
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}
public static function buildTree($rgData, $start = 0, $idKey = 'id', $idParentKey = 'parent_id')
{
self::$tmpData = self::assignKeys($rgData);
$result = self::buildTreeRecursive($start, $idKey, $idParentKey);
return $result;
}
private static function buildTreeRecursive($start, $idKey, $idParentKey)
{
$rgResult = array();
foreach (self::$tmpData as $item) {
if ($item[$idParentKey] == $start) {
$item['children'] = self::buildTreeRecursive($item[$idKey], $idKey, $idParentKey);
$rgResult[] = $item;
}
}
return empty($rgResult) ? null : $rgResult;
}
private static function assignKeys($rgData, $key = 'id')
{
$tmp = array();
foreach ($rgData as $item) {
$tmp[$item[$key]] = $item;
}
return $tmp;
}
}