Проблема: я не могу придумать, как сделать функцию рекурсии для моей конкретной ситуации.
Ситуация:
Mysql DB
id | root | name |
Где root
показывает категорию ведьмы, это подкатегория.
Как должен выглядеть HTML:
<li><a href="#"><p class="Tier0">Datori</p></a> <ul style="display: block"> <li><a href="#"><p class="Tier1">Cookies</p></a></li> <li><a href="#"><p class="Tier1">Events</p></a></li> <li><a href="#"><p class="Tier1">Forms</p></a></li> <li><a href="#"><p class="Tier1">Games</p></a></li> <li><a href="#"><p class="Tier1">Images</p></a> <ul> <li><a href="#"><p class="Tier2">CSS</p></a></li> <li><a href="#"><p class="Tier2">JavaScript</p></a></li> <li><a href="#"><p class="Tier2">JQuery</p></a></li> </ul> </li> <li><a href="#"><p class="Tier1">Navigations</p></a> <ul> <li><a href="#"><p class="Tier2">CSS</p></a></li> <li><a href="#"><p class="Tier2">JavaScript</p></a></li> <li><a href="#"><p class="Tier2">JQuery</p></a></li> </ul> </li> <li><a href="#"><p class="Tier1">Tabs</p></a></li> </ul> </li> <li><a href="#"><p class="Tier0">Washing Machines</p></a>
Какую функцию PHP мне нужно будет распечатать?
Как насчет:
function recurse($categories, $parent = null, $level = 0) { $ret = '<ul>'; foreach($categories as $index => $category) { if($category['root'] == $parent) { $ret .= '<li><a href="#"><p class="Tier' . $level . '">' . $category['name'] . '</p></a>'; $ret .= $this->recurse($categories, $category['id'], $level+1); $ret .= '</li>'; } } return $ret . '</ul>'; }
Эта функция требует, чтобы вы сначала запросили базу данных для всего списка доступных категорий и предположили, что ваши корневые категории имеют значение null, но эту функцию можно изменить, чтобы принять -1 или 0 в зависимости от того, как работает ваша текущая схема.
$categories = { get from database into an multi-dimensional array }; $Tree = $this->recurse($categories); echo $Tree;
Вы можете подумать о том, чтобы сделать следующее, чтобы предотвратить появление пустых UL, если для родителя не существует дочерних элементов:
function recurse($categories, $parent = null, $level = 0) { $ret = '<ul>'; foreach($categories as $index => $category) { if($category['root'] == $parent) { $ret .= '<li><a href="#"><p class="Tier' . $level . '">' . $category['name'] . '</p></a>'; $sub = $this->recurse($categories, $category['id'], $level+1); if($sub != '<ul></ul>') $ret .= $sub; $ret .= '</li>'; } } return $ret . '</ul>'; }
Тем не менее, лучшим решением было бы выбрать ваши данные, чтобы включить столбец, содержащий количество дочерних категорий каждой категории.
select Category.*, (select count(distinct c1.id) from Category as c1 where c1.root = Category.id) as ChildCount from Category
В вашей функции будет:
function recurse($categories, $parent = null, $level = 0) { $ret = '<ul>'; foreach($categories as $index => $category) { if($category['root'] == $parent) { $ret .= '<li><a href="#"><p class="Tier' . $level . '">' . $category['name'] . '</p></a>'; if($category['ChildCount'] > 0) $ret .= $this->recurse($categories, $category['id'], $level+1); $ret .= '</li>'; } } return $ret . '</ul>'; }
Надеюсь, это поможет?