Хочу сделать меню на php, что бы разделы и подразделы этого меню хранились в БД. Будет иерархическая структура разделов. В БД, в табличке следующие поля:
id - ну это ясно.
name - имя раздела, например "Услуги".
parent - родительский раздел(содержит id родителя).
some - условие(показывать или нет этот раздел).
Создаю массив с этими разделами:
$result = mysql_query('SELECT * FROM menu', $db);
$menu = array();
$i = 0;
while($m = mysql_fetch_assoc($result)) //создаём массив всех эллементов меню
{
$menu[$i]['id'] = $m['id'];
$menu[$i]['name'] = $m['name'];
$menu[$i]['parent'] = $m['parent'];
$menu[$i]['some'] = $m['some'];
$i++;
}
А вот как дальше сделать без понятия.

Хочу что бы меню было такого типа:
Раздел 1
Раздел 2
Подраздел 1
->Подраздел 2(мы тут находимся)
Раздел 3
И вот так:
Раздел 1
->Раздел 2(мы тут находимся)
Подраздел 1
Подраздел 2
Раздел 3
В первом случае в разделе 1 тоже есть подразделы, но они не должны показываться.
Во втором случае надо показать только подразделы Раздела 2.
Подскажите, пожалуйсто, а то даже не знаю как подступить к этой штуке.
Спустя 7 минут, 4 секунды (19.12.2009 - 22:19) qpayct написал(а):
я чо то не понял или ты решил сделать выпадающее меню на ПХП?
Спустя 4 минуты, 58 секунд (19.12.2009 - 22:24) Anton63 написал(а):
Цитата (qpayct @ 19.12.2009 - 19:19) |
я чо то не понял или ты решил сделать выпадающее меню на ПХП? |

Спустя 15 минут, 51 секунда (19.12.2009 - 22:40) qpayct написал(а):
добавь в бд:
1 к какому уровню относится раздел
2 вкл/выкл
а потом выгруженные данные в массивы сортируешь по уровню
и т.д и т.п.... в чём проблема то?
1 к какому уровню относится раздел
2 вкл/выкл
а потом выгруженные данные в массивы сортируешь по уровню
и т.д и т.п.... в чём проблема то?
Спустя 20 минут, 52 секунды (19.12.2009 - 23:01) Anton63 написал(а):
Цитата (qpayct @ 19.12.2009 - 19:40) |
а потом выгруженные данные в массивы сортируешь по уровню и т.д и т.п.... в чём проблема то? |
эээ... чёт я не понял...

Каким образом нужно отсортировать массив??? Даже представить не могу как должны быть расположены данные в массиве...
допустим у меня 2 уровня в меню... если по уровням отсортировать то получится так, что сначало идут все разделы 1 уровня, а потом все разделы 2 уровня...
Спустя 19 минут, 57 секунд (19.12.2009 - 23:21) qpayct написал(а):
ну,б... сортируешь как тебе удобно 
при помощи встроеных функций ПХП надо поискать сам не вспомню какие... кажись asort() и arsort()
копай

при помощи встроеных функций ПХП надо поискать сам не вспомню какие... кажись asort() и arsort()
копай

Спустя 31 минута, 16 секунд (19.12.2009 - 23:52) Anton63 написал(а):
Цитата (qpayct @ 19.12.2009 - 20:21) |
кажись asort() и arsort() |
не, это совсем не то...
Пытался сделать чё то типо того:
Это для самого первого уровня меню.
function top($var) //выборка эллементов верхнего уровня меню
{
return($var['parent'] == '');
}
echo array_filter($menu, "top").'<br>';
можно придумать такие же функции и для разделов которые на этом же уровне находятся и т.д.
Но как это всё связать не смог понять... Там много нюансов, которые не получится эти способом решить...
Спустя 3 минуты, 47 секунд (19.12.2009 - 23:56) Anton63 написал(а):
Да и если даже есть массив с разделами, то выводить то не все из них надо... т.к. некоторые из них находятся в другом разделе... Т.е., например мы находимся в разделе 1, и нам показываются все его подразделы... но нам не должны показываться подразделы раздела 2... Как то так...

Спустя 42 минуты, 26 секунд (20.12.2009 - 00:39) dr_Lev написал(а):
Я бы сделал это одним классом. Т.е. класс пункт меню, у него есть свой шаблон (т.е. как он рисуется), признак "выводить/не выводить", ссылка на род. элемент, и массив внутренних эл-тов, которые в свою очередь являются объектами этого же класса...
Вобщем дальше домыслю, напишу
Вобщем дальше домыслю, напишу
Спустя 2 минуты, 6 секунд (20.12.2009 - 00:41) qpayct написал(а):
Я так понимаю ты его с опцией редактирования собрался делать?
1. Создай бд:
id
name
desc
status
level
2. Напиши страничку добавление нового пункта меню.
3. Открытие меню. в sql запросе сразу по уровню доставай ORDER BY level ASC
4. Проверка если status=0 & level=$pagelevel открываем
делов то
1. Создай бд:
id
name
desc
status
level
2. Напиши страничку добавление нового пункта меню.
3. Открытие меню. в sql запросе сразу по уровню доставай ORDER BY level ASC
4. Проверка если status=0 & level=$pagelevel открываем
делов то
Спустя 33 минуты, 34 секунды (20.12.2009 - 01:14) Anton63 написал(а):
Цитата (dr_Lev @ 19.12.2009 - 21:39) |
Я бы сделал это одним классом. Т.е. класс пункт меню, у него есть свой шаблон (т.е. как он рисуется), признак "выводить/не выводить", ссылка на род. элемент, и массив внутренних эл-тов, которые в свою очередь являются объектами этого же класса... |

Спустя 21 минута, 31 секунда (20.12.2009 - 01:36) qpayct написал(а):
Дк в классе тогда и создавай методы открытие, редактирование и т.п. Тыж не хочешь при каждом рефреше открывать бд... Или ты ждёшь что за тебя всё напишут?
Спустя 1 час, 26 минут, 15 секунд (20.12.2009 - 03:02) dr_Lev написал(а):
Вот, попробуй так:
P.S. писал "на колене", извини за ошибки, надеюсь их будет не много
class Menu{
public $items = array();
public $id;
public $name;
public $parent_ = NULL;
public $some;
public $active = false;
public $tpl = '';
public $tpl_a = '';
public function __construct($id,$name,$parent,$some,$tpl,$tpl_a){/*здесь $parent - не id из базы, а или NULL, или ссылка на объект класса Menu, т.е. верхний пункт*/
$this->id = $id;
$this->name = $name;
$this->parent_ = $parent ;
$this->some= $some;
$this->tpl = $tpl;
$this->tpl_a = $tpl_
}
/**
Добавляет пункт
*/
public function AddChild($id,$name,$parent,$some,$tpl,$tpl_a){/*а здесь $parent - уже 'parent' из базы*/
if ($this->id == $parent){// если текущий пункт является родительским для добавляемого...
$this->items[] = new Menu($id,$name,$this,$some,$tpl,$tpl_a);
return true;
}else{// иначе
foreach ($this->items as $item){ // пытаемся добавить пункт в уже именющиеся дочерние пункты
if ($item->AddChild($id,$name,$parent,$some,$tpl,$tpl_a)){ // если добавили в дочерний, дальше продолжать смысла нет, возвращаем true
return true;
}
}
}
// ну а сюда попадем, если добавить пункт не получилось ни в текущий ни в дочерние пункты.
return false;
}
/**
Устанавливает пункт активным
*/
public function SetActive($id){
if ($this->id == $id){
$this->active = true;
if ($this->parent_ != NULL){
$this->parent_->SetActive($this->parent_->id);
}
}else{
foreach ($this->items as $item){
$item->SetActive($id);
}
}
}
private function GetTpl(){
if ($this->active){
return str_replace('{NAME}',$this->name,$this->tpl_a);
}else{
return str_replace('{NAME}',$this->name,$this->tpl);
}
}
public function GetString(){
$str = '';
if ($this->parent_ == NULL){
foreach($this->items as $item){
$str.=$item->GetString();
}
}else{
$str.=$this->GetTpl();
if ($this->active){
foreach($this->items as $item){
$str.=$item->GetString();
}
}
}
return $str;
}
}
$result = mysql_query('SELECT * FROM menu', $db);
$menu = new Menu(0,NULL,NULL,NULL,NULL,NULL);//Создаем объект меню, с пустыми параметрами, т.к. этот пункт не выводится, а служит всего лишь контейнером для всех остальных.
while($m = mysql_fetch_assoc($result)) //создаём массив всех эллементов меню
{
if ($m['parent'] == 0){
$tpl = 'ПУНКТ {NAME}<br />'; // шаблон верхнего уровня не активный
$tpl_a = '<b>ПУНКТ {NAME}</b><br />'; // шаблон верхнего уровня активный
}else{
$tpl = 'подпункт {NAME}<br />'; // шаблон подпункта не активного
$tpl_a = '<b>подпункт {NAME}</b><br />'; // шаблон подпункта активного
}
$menu->AddChild($m['id'],$m['name'],$m['parent'],$m['some'],$tpl,$tpl_a);
}
$menu->SetActive(135);
echo $menu->GetStr();
P.S. писал "на колене", извини за ошибки, надеюсь их будет не много

Спустя 1 день, 19 часов, 58 минут, 43 секунды (21.12.2009 - 23:01) Anton63 написал(а):
dr_Lev, спасибо!!!
Суперски... я бы до такого и не додумался... блин, так вот что такое класс... я просто себе его немного по другому представлял... точнее не представлял, что это такое...
Отлично, теперь буду разбираться и дорабатывать...
Суперски... я бы до такого и не додумался... блин, так вот что такое класс... я просто себе его немного по другому представлял... точнее не представлял, что это такое...
Отлично, теперь буду разбираться и дорабатывать...