Помогите с боковым меню на php+mysql

И всё прочее, что касается HTML
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Помогите с боковым меню на php+mysql

Непрочитанное сообщение daggerok » 2010-03-27 3:57:51

доброго времени суток, товарищи!
подскажите, как реализовать средствами php динамическое боковое меню на подобии того, которое имеется на http://www.lissyara.su (раскрытым должно быть только выбранное подменю и путь до него, все другое должно остаться свернутым). уровень вложенности хотя-бы 3, но хотелось бы без ограничений. если такое возможно имена меню и подменю хранятся можно сказать "как попало", т.е. в не нормализированных таблицах базы на мускуле

может у автора сайта можно попросить исходники того самого меню ну и того, что помогло бы разобраться с вопросом

не пинайте сильно - я в php начинающий

заранее спасибо!

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

Re: Помогите с боковым меню на php+mysql

Непрочитанное сообщение ProFTP » 2010-03-27 16:09:12

я бы сделал в древовидной структуре с parent_id и level уровень узла (отступ с левой границы)
или посто parent_id, а level расчитать

гуглите про "древовидные структуры parent_id" "nestedset" и т.д.
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: Помогите с боковым меню на php+mysql

Непрочитанное сообщение daggerok » 2010-03-27 19:31:57

ProFTP писал(а):гуглите про "древовидные структуры parent_id" "nestedset" и т.д.
о, спасибо, похоже это то что мне нужно

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: Помогите с боковым меню на php+mysql

Непрочитанное сообщение daggerok » 2010-03-27 22:12:10

хм, как-то запутанно все.
чисто теоретически вроде бы понятно что надо создать таблицу дерева, определенными запросами создавать узлы, но как это реализовать в коде на практике в своем файле menu.php которе будет прикрепляться к страничкам функцией include пока не понятно...

Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

Re: Помогите с боковым меню на php+mysql

Непрочитанное сообщение ProFTP » 2010-03-27 23:04:06

вы начните делать...

если дерево не большое будет, то лучше parent id
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: Помогите с боковым меню на php+mysql

Непрочитанное сообщение daggerok » 2010-03-29 0:37:03

значит пока что реализовал дерево с заданной вложенностью, так как по материалам с рекурсиями или parent_id все оч сложно
если вложенность, например, 3 (что мне сейчас подходит), то хранение дерева происходит в трех таблицах.
для тех кому интересно выкладываю свой menu.php:

Код: Выделить всё

<?php 
$db = mysql_connect("localhost","test","test");
mysql_select_db("test",$db);

$result1 = mysql_query("SELECT * FROM `razdel`",$db);
	$razdel = mysql_fetch_assoc($result1);
	if($_GET['razdel_id']) {
		$result2 = mysql_query("SELECT * FROM `sections` WHERE section_id =".$_GET['razdel_id']."",$db);
		$sections = mysql_fetch_assoc($result2);
		}
		if ($_GET['section']) {
			$result3 = mysql_query("SELECT * FROM `subsection` WHERE subsection_id=".$_GET['section']."",$db);
			$subsection = mysql_fetch_assoc($result3);
			}

echo "<ul>";
do {
	printf("<li><a href='?razdel_id=".$razdel['id']."'>%s</a></li>",$razdel['name']);
		   if ($sections && $_GET['razdel_id'] == $razdel['id']) {
			   echo "<ul>";
			   do {
				   printf("<li><a href='?razdel_id=".$razdel['id']."&section=".$sections['id']."'>%s</a></li>",$sections['name']);
						  if ($subsection && $_GET['section'] == $sections['id']) {
							  echo "<ul>";
							  do {
								  printf("<li><a href='?razdel_id=".$razdel['id']."&section=".$sections['id']."&subsection=".$subsection['id']."'>%s</a></li>",$subsection['name']);
								  }while($subsection = mysql_fetch_assoc($result3));
							  echo "</ul>";
							  }
				   }while($sections = mysql_fetch_assoc($result2));
			   echo "</ul>";
			   }
	}while($razdel = mysql_fetch_assoc($result1));
echo "</ul>";
?>
в примере можно использовать такую структуру таблиц для хранения трехуровневого дерева в базе данных (в моем случае test):

Код: Выделить всё

таблица razdel:
 id 	name 	page_id
1 	Раздел 1 	7
2 	Раздел 2 	8
3 	Раздел 3 	9
4 	Раздел 4 	10

Код: Выделить всё

таблица sections:
id 	name 	section_id 	page_id
1 	Подраздел 1.1 	1 	12
2 	Подраздел 1.2 	1 	13
3 	Подраздел 2.1 	2 	14
4 	Подраздел 3.1 	3 	15
5 	Подраздел 4.1 	4 	16
6 	Подраздел 4.2 	4 	17
7 	Подраздел 4.3 	4 	18

Код: Выделить всё

таблица subsection:
id 	name 	subsection_id 	page_id
1 	Поподраздел 1.1.1 	1 	20
2 	Поподраздел 1.2.1 	2 	21
3 	Поподраздел 1.2.2 	2 	22
4 	Поподраздел 4.2.1 	6 	23
5 	Поподраздел 4.2.2 	6 	24
6 	Поподраздел 4.2.3 	6 	25
все тексты страниц хранятся в базе в отдельной таблице с уникальным идентификатором page_id

да, получается не так профессионально как того хотелось бы, но это пожалуй больше всего мне сейчас подойдет, те другие варианты о которых говорил ProFTP какие-то очень сложные для меня, как минимум пока-что..

Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

Re: Помогите с боковым меню на php+mysql

Непрочитанное сообщение ProFTP » 2010-03-29 18:49:30

вот я делал похожее, только не много друго чем у вас, но именно так и нужно сделать...

Код: Выделить всё

sub section_tree : Privat {
    my ( $self, $c, $sc, $privat ) = @_;

    my $sql2;
    my $sql;
    my $sql_sel;

    if ( !$c->check_user_roles('moder_se') ) {

        $sql2 = 'AND active_se = 1
                     AND forbi_section_se = 0
                     AND active_se = 1';

        $sql = 'AND t1.active_se = 1
                     AND t1.forbi_section_se = 0
                     AND t1.active_se = 1';

        $sql_sel = ', close_se,
                                  hiden_g_co';
    }
    else {
        $sql_sel = ', active_se,
                                  close_se,
                                  forbi_section_se,
                                  forbi_content_se,
                                  hiden_g_co';

    }

    my $loop_select;
    my $loop_data;
    my $pn;
    my $pn_id;
    my $sqle;

    if ($sc) {

        my $index = 0;
        my @head  = ();
        my $dbh   = $c->model('DBI')->dbh;
        my $sth;
        while (1) {

            $index++;

            $sth = $dbh->prepare( "
        SELECT t1.parent_se_id,
                    t1.id_se,
                    t1.name_se     
          FROM section AS t1
    
         WHERE t1.id_se = ? 
                 " . ( $sql || '' ) . "
         LIMIT 1
         " );

            if ( $head[-1] ) {
                $sqle = $head[-1];
            }
            else {
                $sqle = $sc;
            }

            $sth->execute($sqle);

            my $name_parrent = $sth->fetchrow_hashref();
            $sth->finish();

            if ( $name_parrent->{parent_se_id} == 0 ) {
                $name_parrent->{name_se} =
                  'The upper level of the tree';
            }

            $sth = $dbh->prepare( "
        SELECT id_se,
                    name_se,
                    parent_se_id
                    $sql_sel
                                  
          FROM section
         WHERE parent_se_id = ? 
                 " . ( $sql2 || '' ) . "
         " );

            my $sqle;

            if ( $head[-1] ) {
                $sqle = $head[$#head];
            }
            else {
                $sqle = $sc;
            }

            $sth->execute($sqle);

            my $loop;

            my $ref_and;

            while ( my $ref = $sth->fetchrow_hashref() ) {

                if ( $c->check_user_roles('moder_se') ) {
                    $ref->{close_se}  = $ref->{close_se} == 1  ? '1' : undef;
                    $ref->{active_se} = $ref->{active_se} == 0 ? '1' : undef;
                    $ref->{forbi_section_se} =
                      $ref->{forbi_section_se} == 1 ? '1' : undef;
                    $ref->{forbi_content_se} =
                      $ref->{forbi_content_se} == 1 ? '1' : undef;
                    $ref->{hiden_g_co} = $ref->{hiden_g_co} == 1 ? '1' : undef;
                }

                if (   $ref->{id_se}
                    && $pn_id->[-1]
                    && $ref->{id_se} eq $pn_id->[-1] )
                {

                    $ref_and = $ref;
                    next;
                }

                push( @{$loop}, $ref );

            }
            $sth->finish();

            my $no_select;

            if ($ref_and) {
                unshift @{$loop}, { %{$ref_and} };
            }

            if ( !$loop ) {

                $no_select = 1;
                $loop      = 0;
            }

            my $no_no_select;
            if ( $sc eq $name_parrent->{id_se} ) {
                $no_no_select = 1;
            }

            my %select;

            if ( !$no_select ) {
                $select{SELECT} = $loop;
            }

            push(
                @{$loop_select},
                {
                    NO_NO_SELECT => $no_no_select,
                    %select,
                    NO_SELECT => $no_select,
                    NAME      => $name_parrent->{name_se},
                    NUMBER    => $index
                }
            );

            push @head, $name_parrent->{parent_se_id};

            push @{$pn},    $name_parrent->{name_se};
            push @{$pn_id}, $name_parrent->{id_se};

            my $id = $name_parrent->{id_se};

            last if ( $id eq '1' || $id eq '35' || $index > 20 );

        }

    }

    if ($sc) {
        if ($loop_select) {
            @{$loop_select} = reverse @{$loop_select};
            $c->stash->{loop_select} = $loop_select;
        }
        else {
            $c->stash->{no_loop_select} = 1;
        }
    }

    if ($loop_data) {
        $c->stash->{select_section} = $loop_data;
    }
    else {
        $c->stash->{no_select_section} = 1;
    }

    $c->stash->{selecting}    = $pn->[0];
    $c->stash->{selecting_id} = $pn_id->[0];

}



 
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: Помогите с боковым меню на php+mysql

Непрочитанное сообщение daggerok » 2010-03-30 10:06:58

ProFTP, спасибо! пока что я туговато ООП воспринимаю :) но так или иначе знал, что рано или поздно придется разбираться с классами - а тут и реальный пример попался.