• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

vpess

Menu de categorias/subcategorias sem limite de niveis

18 mensagens neste tópico

Boas.

Precisava de construir um menu de categorias sem limite de níveis ou seja:

Tabela Categorias

| idcat | idpai | Nome |

- Em que as categorias de nível 1 seriam as que tinham o idpai vazio;

- As categorias de níveis posteriores teriam o idpai preenchido com o idcat a que pertencem;

Isto permitiria ter um menu de categorias ilimitado.

O problema é conseguir criar um query que faça isto mesmo.

Peço então a vossa ajuda para me ajudarem a construir esta query, em php e mysql.

Cumprimentos.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas o query para isso é simples o que depois tens de fazer é usar esse resultado e passa-lo numa função que te construa  a arvore da forma correcta.

Vê o seguinte exemplo pode ser que ajude:

http://programacao.maistemas.com/php/funcao-para-criar-um-array-com-categorias-em-forma-de-arvore/

e

http://programacao.maistemas.com/php/funcao-para-criar-um-array-de-categorias-em-forma-de-arvore-parte-2/

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se precisares de código para isso, apita : aeon.yoda@gmail.com

É preferível que essa ajuda seja dada aqui no fórum, assim fica disponível a quem tiver essa dúvida. :(

Anyway, a query é um simples select, depois é só construíres a estrutura:

$cats = array(0 => array('childs' => array(), 'name' => 'Portugal-a-Programar');
while($r = fetcharray()){
    $cats[$r['idpai']]['childs'][] = $r['idcat'];
    $cats[$r['idcat']]['name'] = $r['Nome'];
}

Este código assume que não existe na BD uma row com idcat 0 (ou seja, o nível anterior ao 1o do menu). Depois é só pegares naquilo e fazeres o menu:

function struct2menu($x = 0, $level = 0){
    global $cats;
    echo str_repeat("    ", $level), $cats[$x]['name'], "<br />\n";
    foreach($cats[$x]['childs'] as $id){
        struct2menu($id, $level+1);
    }
}

struct2menu() deve devolver algo como:

Portugal-a-Programar
    Forum
        PHP
            Dúvidas e Ajudas
            Tutoriais
        JavaScript
            Dúvidas
                Ajudas
                    Tutoriais
                        Tretas
                            Browsers
                                Lulz
                                    Lulzware
                                        Adriana Lima
                                            grabs
                                                her husband's
                                                    crotch
                                        Babes
                        XPTO
            Lulz
        SPAM SPAM
            SPAM
                Monty's
    PasteBin
        SPAM
            Babes
        Code

Se fizeres

foreach($cats[0]['childs'] as $ids){
    struct2menu($ids, 0);
}

Ele deixa de mostrar o "Portugal-a-Programar" e recua tudo 1 nível (4 nbsp).

Btw, não testei o código.

EDIT: Rectifiquei umas coisinhas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Vou mas é escrever um tutorial ou algo parecido a explicar como conseguir um sistema de categorias e subcategorias, e respectivos menus desdobráveis ... Quando tiver tempo :(

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Vou mas é escrever um tutorial ou algo parecido a explicar como conseguir um sistema de categorias e subcategorias, e respectivos menus desdobráveis ... Quando tiver tempo :(

Os links que eu coloquei acima são o inicio desse Tutorial :), faltam ainda os outros passos que é o CSS e o JavaScript.

Mas para se ficar com uma ideia o resultado final seria este, que esta nesta página.

http://servidorb.com/unitree/

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas,

Estive a pesquisar e encontrei este exemplo na net:

http://www.elmicox.com/2008/fazer-um-menu-com-varios-niveis-bd-php-js-css/

function gera_menu($cod_ul_pai,$tabs,$id_do_pai){
    //gera um menu ul com submenus
    //by Micox - elmicox.blogspot.com - forum.ievolutionweb.com
    //exemplo: gera_menu("<ul>","    ",0)
    $recc = mysql_query("SELECT * FROM menus WHERE pai_id=$id_do_pai AND visivel=1 ORDER BY ordem");
    $ret = $cod_ul_pai."\r\n";
    if($recc==true){
        while($linha = mysql_fetch_array($recc,MYSQL_ASSOC)){
            if(isset($linha['link'])){
                $href = $linha['link'];
            }else{
                $href = '';
            }
            $ret .= $tabs."    <li><a href='$href'>".htmlentities($linha['nome'])."</a>";
            //testando se tem filhos
                $recfilho = mysql_query("SELECT * FROM menus WHERE pai_id=$linha[id] AND visivel=1 ORDER BY ordem");
                if(mysql_num_rows($recfilho)>0){
                    $ret .= "\r\n".$tabs."        ".gera_menu("<ul>",$tabs."        ",$linha['id'])."    ".$tabs;
                }
            //fim filhos
            $ret .= "</li>\r\n";
        }
    }
    $ret .= $tabs."</ul>\r\n";
    mysql_free_result($recc);
    return $ret;
}
?>
<?php echo gera_menu("<ul>","        ",0) ?>

Agora também coloco a questão.

Será complicado adaptar este código para ligação com BD em Sql Server???

Dava-me muito jeito. :(:)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Assim olhando de repente para a função o que eu aponto como negativo, é os cilcos de chamadas à base de dados, se imaginares que tens 5000 categorias (sei que é muito, mas para se ter uma ideia) podera ter de fazer dezenas, senão centenas de chamadas à base de dados para construir a estrutura de categorias, e logico que, pensado que, se o teu site tiver 1000 visitantes ao mesmo tempo (mais uma vez sei que é muito, mas prontos) imagina o que o servidor tem de dar ao pedal para processar todas essas chamadas :(

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O código que aí meteste é praticamente igual ao meu lol, é só pegares no meu e adaptares para gerar o menu com o formato que queres e usares as funções para MS SQL Server.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O código que aí meteste é praticamente igual ao meu lol, é só pegares no meu e adaptares para gerar o menu com o formato que queres e usares as funções para MS SQL Server.

Então vamos la ver.

Eu estive a alterar as funções para Sql Server mas dá-me uns erros:

Warning: odbc_exec(): supplied argument is not a valid ODBC-Link resource in C:\AppServ\www\ajcordeiro\index.php on line 30

Warning: odbc_free_result(): supplied argument is not a valid ODBC result resource in C:\AppServ\www\ajcordeiro\index.php on line 46

<?php 

        $connection_string = 'Driver={SQL Native Client};Server=xxxxxxxx;Database=xxxxx; Trusted_Connection=no;'; 
        $user = 'xxxx'; 
        $pass = 'xxxx'; 
        $conn = odbc_connect( $connection_string, $user, $pass ); 
		  
  
function gera_menu($cod_ul_pai,$tabs,$id_do_pai){
    //gera um menu ul com submenus
    //by Micox - elmicox.blogspot.com - forum.ievolutionweb.com
    //exemplo: gera_menu("<ul>","    ",0)
    $ss = "SELECT * FROM stfami";
    $recc = odbc_exec($conn, $ss);
    $ret = $cod_ul_pai."\r\n";
    if($recc==true){
        while($linha = odbc_fetch_array($recc,MYSQL_ASSOC)){
            
            $ret .= $tabs."    <li><a href='$href'>".htmlentities($linha['design'])."</a>";
            //testando se tem filhos
                $recfilho = odbc_exec("SELECT * FROM stfami WHERE u_stamppai=$linha[stampstfami]");
                if(odbc_num_rows($recfilho)>0){
                    $ret .= "\r\n".$tabs."        ".gera_menu("<ul>",$tabs."        ",$linha['stampstfami'])."    ".$tabs;
                }
            //fim filhos
            $ret .= "</li>\r\n";
        }
    }
    $ret .= $tabs."</ul>\r\n";
    odbc_free_result($recc);
    return $ret;
}
?>
<?php echo gera_menu("<ul>","        ",0)?>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Falta-te um global $conn; no início da declaração da função. O scope não é o mesmo. :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Adriana Lima

                                            grabs

                                                her husband's

                                                    crotch

:)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Falta-te um global $conn; no início da declaração da função. O scope não é o mesmo. :)

Boas,

Obrigado, resultou.

Mas.... Continuo com um erro.

Fatal error: Maximum execution time of 60 seconds exceeded in C:\AppServ\www\ajcordeiro\index.php on line 41

<?php
            

function gera_menu($cod_ul_pai,$tabs,$id_do_pai){
    //gera um menu ul com submenus
    //by Micox - elmicox.blogspot.com - forum.ievolutionweb.com
    //exemplo: gera_menu("<ul>","    ",0)
global $conn; 
    $ss = "SELECT * FROM stfami";
    $recc = odbc_exec($conn, $ss);
    $ret = $cod_ul_pai."\r\n";
    if($recc==true){
        while($linha = odbc_fetch_array($recc,ODBC_ASSOC)){
           
            $ret .= $tabs."    <li><a href='$href'>".htmlentities($linha['design'])."</a>";
            //testando se tem filhos
                $recfilho = odbc_exec($conn, "SELECT * FROM stfami WHERE u_stamppai='".$linha['stampstfami']."'");
                if(odbc_num_rows($recfilho)>0){
                    $ret .= "\r\n".$tabs."        ".gera_menu("<ul>",$tabs."        ",$linha['stampstfami'])."    ".$tabs;
                }
            //fim filhos
            $ret .= "</li>\r\n";
        }
    }
    $ret .= $tabs."</ul>\r\n";
    odbc_free_result($recc);
    return $ret;
}
?>
<?php echo gera_menu("<ul>","        ",0)?>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isso é porque essa função é lenta. Ou alteras o código para algo mais rápido, ou então usas o set_time_limit para aumentar o tempo limite de execução.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Porque utilizas odbc?

Altera por mysql_connect e mysql query, para bd mysql não se justifica o uso do odbc.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Porque utilizas odbc?

Altera por mysql_connect e mysql query, para bd mysql não se justifica o uso do odbc.

Aquela classe está a funcionar com bd em mysql.

Mas como referi num post em cima, também me era util ter isto a funcionar com bd em Sql Server, daí o odbc.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Lembro-me de ter auxiliado numa pergunta parecida:

http://www.portugal-a-programar.pt/forums/topic/0-find-topic/?do=findComment&comment=269572

Mas vendo bem, a função é semelhante...

E yoda.pt (ou qualquer um que se disponibilize a fazer), explicar como fazer um menu com submenus em PHP sem limite seria um excelente tutorial para a WIKI, secção de PHP ;)

Assim que tiver tempo, deixo isso por aqui :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora