melomaniac
(Melomaniac2012)
May 6, 2014, 12:14pm
1
Всем привет, есть таблица со столбцами id, parent_id, name, пытаюсь вывести список(дерево) учитывая уровень вложенности, покопался в гугле, нашел функцию https://gist.github.com/samdark/3016663 , немного дополнил, все получилось, но я почти уверен что есть более красивое решение, чем это:
public function getCatList()
{
$categories = Category::model()->findAll();
foreach ($categories as $key => $value)
{
if($value->parent_id == 0)
{
$cat[$value->id][] = array("parent_id"=>$value->parent_id, "name"=>$value->name);
}else{
$cat[$value->parent_id][] = array("parent_id"=>$value->parent_id, "name"=>$value->name);
}
}
krsort($cat);
$parent_id=0;
foreach ($cat as $key => $value) {
foreach ($value as $k => $item) {
if($item['parent_id']==$parent_id) {
echo "</li>\n";
}
else if($item['parent_id']>$parent_id) {
echo "<ul>\n";
}else{
echo "</li>\n";
for($i=$parent_id-$item['parent_id'];$i;$i--) {
echo "</ul>\n</li>\n";
}
}
echo "<li>";
echo $item['name'];
$parent_id=$item['parent_id'];
}
for($i=$parent_id;$i;$i--) {
echo "</li>\n</ul>\n";
}
}
}
Соответственно получаю
Новости
-Авторынок
-Автопром
-Автожизнь
-Происшествия
-Выставки
BMW
-Acura
Bentley
Audi
Alfa Romeo
Все работает вроде, но как я и говорил, хотел бы узнать ваше мнение, возможно есть более правильные варианты решения данной задачи, в гугле одни рекурсии, здесь ее вроде как нет
ineersa
(Ineersa)
May 6, 2014, 12:29pm
2
Можно как то так, если AR и рекурсия:
public function getCategories() {
$criteria = new CDbCriteria;
$criteria->order = 'parent ASC';
$categories = self::model()->findAll($criteria);
return $this->buildTree($categories);
}
protected function buildTree(&$data, $rootID = 0) {
$tree = array();
foreach ($data as $id => $node) {
if ($node->parent == $rootID) {
unset($data[$id]);
$node->childs = $this->buildTree($data, $node->id);
$tree[] = $node;
}
}
return $tree;
}
Обращаться с ним потом так как вам нужно:
$categoriesTree = $this->getCategories();
foreach ($categoriesTree as $category) {
if ($category->parent == 0) {
//собственно $category - ваша родительская категория
//$category->childs - дети
}
}
melomaniac
(Melomaniac2012)
May 6, 2014, 12:38pm
3
ineersa:
Можно как то так, если AR и рекурсия:
public function getCategories() {
$criteria = new CDbCriteria;
$criteria->order = 'parent ASC';
$categories = self::model()->findAll($criteria);
return $this->buildTree($categories);
}
protected function buildTree(&$data, $rootID = 0) {
$tree = array();
foreach ($data as $id => $node) {
if ($node->parent == $rootID) {
unset($data[$id]);
$node->childs = $this->buildTree($data, $node->id);
$tree[] = $node;
}
}
return $tree;
}
Обращаться с ним потом так как вам нужно:
$categoriesTree = $this->getCategories();
foreach ($categoriesTree as $category) {
if ($category->parent == 0) {
//собственно $category - ваша родительская категория
//$category->childs - дети
}
}
Спасибо, надо будет потестить ради интереса что меньше ресурсов ест, хотя категорий будет не более 100 я думаю
melomaniac
(Melomaniac2012)
May 6, 2014, 12:44pm
4
Загнулся мой мега код на 3 уровне вложенности, вывел вообще третий уровень в другом месте
ineersa
(Ineersa)
May 6, 2014, 1:25pm
5
Вот собственно вывод самого меню:
public static function getLeveledMenu($genres)
{
$output="<ul>";
foreach($genres as $genre){
$output.="<li>".$genre->title."</li>";
if (!empty($genre->childs)){
$output.=self::getLeveledMenu($genre->childs);
}
}
$output.="</ul>";
return $output;
}
На скорую руку писал, но должно работать. У меня немного другая ситуация, у детей еще может быть по несколько родителей, и я записал в таблицу немного не правильно. Возможно сейчас переделаю, или что то придумаю. У меня порядка 600 категорий, отрабатывает быстро.
ineersa:
Вот собственно вывод самого меню:
public static function getLeveledMenu($genres)
{
$output="<ul>";
foreach($genres as $genre){
$output.="<li>".$genre->title."</li>";
if (!empty($genre->childs)){
$output.=self::getLeveledMenu($genre->childs);
}
}
$output.="</ul>";
return $output;
}
На скорую руку писал, но должно работать. У меня немного другая ситуация, у детей еще может быть по несколько родителей, и я записал в таблицу немного не правильно. Возможно сейчас переделаю, или что то придумаю. У меня порядка 600 категорий, отрабатывает быстро.
Спасибо, остановился на рекурсии, а так хотел сделать без нее