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

Buh#

[RESOLVIDO] MENU DINÂMICO

26 mensagens neste tópico

Boas pessoal, sou iniciante em php e estou a tentar fazer um menu dinâmico. Já pesquisei na net, mas ainda não consegui deixar o código a funcionar.

Se me dessemm uma ajudinha, agradecia! ;)

Tenho o seguinte código:

mysql_connect("localhost", "blablabla", "blablabla") or die ("Impossivel ligar ao servidor!<p>");
	$sql="select categorias.*, cat.nome AS pai_nome FROM categorias LEFT JOIN categorias AS cat ON categorias.pai = cat.id where pai ='".$id."'";
	$resultado=mysql_db_query ("blablabla", $sql);

	function menu($pai=0)
{
	while ($registos = $resultado)
	{
		menu($pai=$registo['pai_nome']);

		echo ($pai);
				if ($pai=0)
					{
						//menu($pai["pai_nome"]);
						menu($pai);
						//echo ($pai);
					}
					}
	mysql_close();
	mysql_free_result ($resultado);
}
	menu();

$pai - é o id do pai...

Va lá malta ajudem-me a seguir em frente.  ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tens aí uma função recursiva pelo meio, suponho que seja para fazer os submenus... Não consigo é perceber como tens a tua base de dados organizada, se puderes deixar aqui, seria útil para a resolução do teu problema.

Para além disso, essa função mysql_db_query parece ter sido descontinuada no PHP 5, troca por mysql_query($sql), que é compatível com ambas as versões.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tens aí uma função recursiva pelo meio, suponho que seja para fazer os submenus... Não consigo é perceber como tens a tua base de dados organizada, se puderes deixar aqui, seria útil para a resolução do teu problema.

Para além disso, essa função mysql_db_query parece ter sido descontinuada no PHP 5, troca por mysql_query($sql), que é compatível com ambas as versões.

Sim, é para os sub-menus. Mas estou a ir por partes para ser mais fácil, visto que estou no principio.

na bd tenho os campos, id; pai; nome. E queria só usar estes se desse.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para mostrar os pais tenho assim:

	if ($resultado)
{
	while ($registo=mysql_fetch_array($resultado))
	{
		$nome=$registo["nome"];
		print ("<td><align=center>$nome<p></tr></td>");
	}

}
else
{
	print ("Não há registos!");
}
mysql_free_result ($resultado);

Preciso é de agora ir chamar os filhos com uma function...  ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Em vez de uma função recursiva, podes é efectuar queries dentro teu ciclo. Ou seja, tu seleccionas todos os menus de raiz (em principio serão aqueles que não têm um pai), e dentro do ciclo, em que vais buscar cada "pai", fazes uma nova query, a perguntar quem sao os filhos, exmeplo:

// seleccionar os menus "de topo" (sem menu superior na sua hierarquia)
$q = mysql_query("SELECT .... WHERE pai = NULL");

while ($pai=mysql_fetch_array($q)) {
  $nome=$pai["nome"];
  echo "<td><align=center>$nome<p></tr></td>";
  
  // procurar menus "filhos", que têm como pai o actual
  $qf = mysql_query("SELECT ... WHERE pai = '$nome'")
  while ($filho =  mysql_fetch_array($qf)) {
    echo "<li>{$filho['nome']}</li>";
  }
}

esta solução funciona para menus com apenas um nível de submenus. Caso tenhas submenus dentro de submenus é um bocado mais complicado e terás de usar recursividade tal como estavas a fazer.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu tenho a class Mysql e depois fiz uma class para a listagem dos menus,submenus e submenus de submenus...está assim:

   $this->mySQL=$mySQL = new MySQL();
   $mySQL->conecta();
   $mySQL->db=$_SESSION['CONFIG']['DB'];   
   $n=0;
   $n2=1;   
   $resultado_menus=$mySQL->sql("SELECT *FROM paginas WHERE tipo='menu' ORDER BY posicao");
   
   
          $menus_html.='<h4 align="center">'.C_HEADER1.'</h4>
	                <div id="index_tab">
                        <div style="width:10%;" >ID</div>
			        <div style="width:10%;" >'.C_ACTIVO.'</div>
                        <div style="width:10%;" >'.C_TIPO.'</div>
                        <div style="width:51%;">'.C_TITULO.'</div>
					<div style="width:5%;">...</div>
					</div>
					<div style="clear:both;"></div>';


    while($m_row=mysql_fetch_array($resultado_menus)){	
$resultado_submenus=$mySQL->sql("SELECT *FROM paginas WHERE tipo='submenu' and parent='".$m_row['id']."' ORDER BY posicao");

if(!mysql_num_rows($resultado_submenus)==0){$submenus="yes";}else{$submenus="no";}
  
 $menus_html.='<div id="index_tab_menus">
                   <div style="width:10%;" >'.$this->FixSub('submenu',$n,$submenus).''.$m_row['id'].'</div>
			   <div style="width:10%;" >'.$this->estado($m_row['estado']).'</div>
                   <div style="width:10%;" ><b>'.$this->tipoCheck($m_row['indice'],$m_row['password']).'</b></div>
                   <div style="width:51%;" >
			     <a href="'.$this->UrlCheck($m_row['indice'],$m_row['id']).'">
				 <b>'.$this->coded($m_row['titulo']).'</b>
				 </a>
			   </div>
                   <div style="width:43px;">
			     <a  href="?app='.$m_row['edit_link'].'&id='.$m_row['id'].'" >
                     <img src="styles/template/edit.gif"  title="'.C_EDITAR.'"border="0" />
				 </a>';
				 if($m_row['indice']<>"homepage"){
   $menus_html.='<a  href="?app='.$m_row['del_link'].'&id='.$m_row['id'].'" >
			     <img src="styles/template/del.gif"  title="'.C_ELIMINAR.'" border="0"/>
				 </a>';}
     $menus_html.='</div>
			   </div>';
	  
  
     
	   if($submenus=="yes"){
	   while($s_row=mysql_fetch_array($resultado_submenus)){
$resultado_multinivel=$mySQL->sql("SELECT *FROM paginas WHERE tipo='multinivel' and parent='".$s_row['id']."' ORDER BY posicao");
     if(!mysql_num_rows($resultado_multinivel)==0){$multinivel="yes";}else{$multinivel="no";}
				   
 $menus_html.='<div id="index_tab_submenus" class="sub_'.$n.'">
                   <div style="width:10%;" >'.$this->FixSub('multinivel',$n2,$multinivel).''.$s_row['id'].'</div>
			   <div style="width:10%;" >'.$this->estado($s_row['estado']).'</div>
                   <div style="width:10%;" >'.$this->tipoCheck($s_row['indice'],$s_row['password']).'</div>
                   <div style="width:51%;" >
			   <span id="tab_i_text">'.$m_row['titulo'].'-></span>
			     <a href="'.$this->UrlCheck($s_row['indice'],$s_row['id']).'">
				 <b>'.$this->coded($s_row['titulo']).'</b>
				 </a>
			   </div>
                   <div style="width:43px;" id="row">
			     <a  href="?app='.$s_row['edit_link'].'&id='.$s_row['id'].'" >
                     <img src="styles/template/edit.gif" height="16" hspace="2" title="'.C_EDITAR.'"border="0" />
				 </a>
			     <a href="?app='.$s_row['del_link'].'&id='.$s_row['id'].'">
			     <img src="styles/template/del.gif" height="16" hspace="2" title="'.C_ELIMINAR.'" border="0"/>
				 </a>
                   </div>
			   </div>';
			   
			   if($multinivel=="yes"){
			   $menus_html.='<div class="sub_'.$n.'">';
	              while($f_row=mysql_fetch_array($resultado_multinivel)){
				   
                  $menus_html.='<div id="index_tab_multinivel" class="multi_'.$n2.'">
                                    <div style="width:10%;" id="row" >
								'.$f_row['id'].'</div>
			                    <div style="width:10%;" >'.$this->estado($f_row['estado']).'</div>
                                    <div style="width:10%;" ><b>'.$this->tipoCheck($f_row['indice'],$f_row['password']).'</b></div>
                                    <div style="width:51%;" >
								<span id="tab_i_text">'.$m_row['titulo'].'->'.$s_row['titulo'].'-></span>
			                    <a href="'.$this->UrlCheck($f_row['indice'],$f_row['id']).'">
				                <b>'.$this->coded($f_row['titulo']).'</b>
				                </a>
			                    </div>
                                    <div style="width:43px;" id="rowed" >
			                    <a  href="?app='.$f_row['edit_link'].'&id='.$f_row['id'].'" >
                              <img src="styles/template/edit.gif" height="16" hspace="2" title="'.C_EDITAR.'"border="0" />
				               </a>
			                   <a href="?app='.$f_row['del_link'].'&id='.$f_row['id'].'">
			                <img src="styles/template/del.gif" height="16" hspace="2" title="'.C_ELIMINAR.'" border="0"/>
				           </a>
                               </div>
			               </div>';
			   
			   
		             }//MULTINIVEL WHILE END//
					 $n2++;
					 $menus_html.='</div>';
				  }
			   
			   
		  }//SUBMENUS WHILE END//
         

           }  
$n++;
            $menus_html.='<div id="index_tab_menus_end"></div>';
}//MENUS WHILE END/

Não está um código muito simples de perceber porque foi retirado directo de uma app minha nem limpei um pouco pa perceberes.. mas o que tá ai a mais e algumas DEFINES e funcoes da class desnecessárias para o teu caso, mas a essência está ai que são os whiles necessárias e uma maneira de como podes "perguntar" se existe submenus ou multiniveis(submenus de submenus)...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

ainda precisas de ajuda?

posso enviar-te código se quiseres

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Agradeço todas as vossas dicas e acredito que também seriam soluções fiáveis!  :)

Mas eu queria usar a função recursiva, porque é para ter submenus dentro de submenus e por aí fora. Se me pudessem ajudar com a função...  :)

Mas obrigado pelas outras dicas, que entretanto enquanto não me ajudam vou fazendo assim como disseram, mas aguardo um empurrãozito na funciton.  :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ah e reparei que num exemplo mostraram $filho. Eu não tenho nenuhm campo filho na bd.

Só tenho:

id;

pai;(id do pai)

nome;

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

funcao listar(idPai=0)

  cmd = select * from items where idPai=idPai

enquanto cmd.eof entao

  output += outputQueQueres +listar(cmd.IDdoItem);

retorna output;

Alguma coisa do genero ajuda?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ah e reparei que num exemplo mostraram $filho. Eu não tenho nenuhm campo filho na bd.

Só tenho:

id;

pai;(id do pai)

nome;

O "Filho" é o item que estas a iterar actualmente, só precisas de saber o pai, tudo o que nao tiver pai é porque é root

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

funcao listar(idPai=0)

  cmd = select * from items where idPai=idPai

enquanto cmd.eof entao

  output += outputQueQueres +listar(cmd.IDdoItem);

retorna output;

Alguma coisa do genero ajuda?

desculpa lá cyclop, não entendi muito bem o exemplo!  :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não sei se é relevante ou não para a resolução da dúvida, mas tenho assim o código que mostra os pais e os filhos. Gostava só de utilizar a função para aprender...

mysql_connect("localhost", "user, "pass") or die ("Impossivel ligar ao servidor!<p>");
	$sql="select categorias.*, cat.nome AS pai_nome FROM categorias LEFT JOIN categorias AS cat ON categorias.pai = cat.id where categorias.pai =0";
	//$resultado=mysql_query($sql);
	$resultado=mysql_db_query("bd" ,$sql);

if ($resultado)
{

	while ($pai=mysql_fetch_array($resultado))
	{
		$nome=$pai["nome"];
		echo "<td><align=center>$nome<p></tr></td>";
	}

		$qf = mysql_query("select categorias.*, cat.nome AS pai_nome FROM categorias LEFT JOIN categorias AS cat ON categorias.pai = cat.id where categorias.pai <> 0");
		while ($filho=mysql_fetch_array($qf)) 
	{
	//$nome=$filho["nome"];
   		echo "<li>{$filho['nome']}</li>";	
	}

}
else
{
	print ("Não há registos!");
}
mysql_free_result ($resultado);

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ok, tenta então o seguinte, com algumas alterações que

function printSubmenus($idpai="", $pai="") {
  if ($idpai == "") {
    // fazer aqui a query para ir buscar todos os "pais de topo" (nao têm pais)
    $q = mysql_query("select .... where pai = NULL");
  } else {
    // buscar cada filho e ver os seu filhos
    $q = mysql_query("select .... where pai = '$idpai'");
  }
  
  echo $pai;

  while ($filho=mysql_fetch_array($q)) {
    printSubmenus($filho['nome'], $filho['id']);
  }
}

Ou seja, começamos por procurar todos os pais, e por cada um, ver os seus filhos. A função termina quando acabam os filhos, ou seja, não faz mais nada. Tens de corrigir aí os pormenores das queries e  formatação, mas penso que funciona. Não testei.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ok, tenta então o seguinte, com algumas alterações que

function printSubmenus($idpai="", $pai="") {
  if ($idpai == "") {
    // fazer aqui a query para ir buscar todos os "pais de topo" (nao têm pais)
    $q = mysql_query("select .... where pai = NULL");
  } else {
    // buscar cada filho e ver os seu filhos
    $q = mysql_query("select .... where pai = '$idpai'");
  }
  
  echo $pai;

  while ($filho=mysql_fetch_array($q)) {
    printSubmenus($filho['nome'], $filho['id']);
  }
}

Ou seja, começamos por procurar todos os pais, e por cada um, ver os seus filhos. A função termina quando acabam os filhos, ou seja, não faz mais nada. Tens de corrigir aí os pormenores das queries e  formatação, mas penso que funciona. Não testei.

$idpai e o $filho vão buscar que valores!??!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

$filho é controlado pelo código da aplicação, e não é intenção seres tu a preencher.

O valor inicial de pai, deve ser vazio, para efectuar a primeira query. Fiz assim para ter tudo completamente dentro da função recursiva mas, alternativamente, podes passar a parte de obter os pais para fora da função, e num for, chamas a função com o nome e id de cada pai.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

$filho é controlado pelo código da aplicação, e não é intenção seres tu a preencher.

O valor inicial de pai, deve ser vazio, para efectuar a primeira query. Fiz assim para ter tudo completamente dentro da função recursiva mas, alternativamente, podes passar a parte de obter os pais para fora da função, e num for, chamas a função com o nome e id de cada pai.

Estou um bocado baralhado.

Tipo este código é necessário?

if ($resultado)
{
	while ($pai=mysql_fetch_array($resultado))
	{
		$nome=$pai["nome"];
		echo "<td><align=center>$nome<p></tr></td>";
	}

		$qf = mysql_query("select categorias.*, cat.nome AS pai_nome FROM categorias LEFT JOIN categorias AS cat ON categorias.pai = cat.id where categorias.pai <> 0");
		while ($filho=mysql_fetch_array($qf)) 
	{
	//$nome=$filho["nome"];
   		echo "<li>{$filho['nome']}</li>";	
	}

}
else
{
	print ("Não há registos!");
}
mysql_free_result ($resultado);

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O objectivo da função que coloquei é teres a possibilidade de possuir uma quantidade de submenus dentro de submenus ilimitada. Com a função que tens com os dois while (em cima), apenas consegues fazer root e um nivel de submenus, logo não precisas disso.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu acho que a solução e aplicar whiles dentro de whiles se queres menus submenus e multinivel.. agora se queres menus submenus multinivel, submenu de multinivel e por ai a fora seria criares uma funcão com dois parametros iniciais tipo listaMenus($Id,$from) ou uma class bem estruturada, e secalhar por ventura inserires nas tuas tabelas um indice de orientacao para os whiles ou através de IDS com autoIncrement...tens inúmeras maneiras.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Estou com o código assim e não aprece nada no ecrã. Não vejo onde esteja o problema!  :D

mysql_connect("localhost", "user", "pass") or die ("Impossivel ligar ao servidor!<p>");

function printSubmenus($pai="")
{
  if ($pai=0)
  {
    $q = mysql_query("select * FROM categorias where pai = 0");
  } else {
    $q = mysql_query("select * FROM categorias where pai = $pai");
  }
  //echo $pai;

  while ($filho=mysql_fetch_array($q))
  	{
	echo $filho["nome"];
    printSubmenus($filho["id"]);
  	}
}

printSubmenus(0);

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A minha função não contempla o caso de imprimir os elementos de raiz. Tenta executá-la num ciclo em que só vais buscar os elementos de raiz e depois chamas a função para obter os respectivos filhos.

$qp = mysql_query("seleccionar todos os pais");

while ($pai = mysql_fetch_row($qp)) {
  echo $pai['nome'];
  printSubmenus($pai['id']);
}

em que a função passa a ser:

function printSubmenus($pai)
{
  $q = mysql_query("select * FROM categorias where pai = $pai");

  while ($filho=mysql_fetch_array($q))
        {
                echo $filho["nome"];
                printSubmenus($filho["id"]);
        }
}

Pronto, penso que assim já resolva o problema. Dá um jeito às queries para o que pretenderes.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem malta finalmente consegui o meu menu dinâmico. Deixo aqui o código para se alguem precisar. Dá para ter filhos dentro dos filhos sem problemas...

<?php
mysql_connect("localhost", "user", "pass") or die ("Impossivel ligar ao servidor!<p>");
$qp = mysql_query("select * FROM categorias where pai = 0");
$resultado=mysql_db_query("bd" ,$qp);

while ($pai = mysql_fetch_row($resultado)) {
  echo $pai["nome"];
  printSubmenus($pai["id"]);
}


function printSubmenus($pai)
{
  $q = mysql_query("select * FROM categorias where pai = $pai");

  echo "<ul>";
  while ($filho=mysql_fetch_array($q))
        {
                echo "<ul><li>{$filho["nome"]}</li></ul>";
                printSubmenus($filho["id"]);
        }
echo "</ul>";
}
printSubmenus(0);
?>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem malta finalmente consegui o meu menu dinâmico. Deixo aqui o código para se alguem precisar. Dá para ter filhos dentro dos filhos sem problemas...

<?php
mysql_connect("localhost", "user", "pass") or die ("Impossivel ligar ao servidor!<p>");
$qp = mysql_query("select * FROM categorias where pai = 0");
$resultado=mysql_db_query("bd" ,$qp);

while ($pai = mysql_fetch_row($resultado)) {
  echo $pai["nome"];
  printSubmenus($pai["id"]);
}


function printSubmenus($pai)
{
  $q = mysql_query("select * FROM categorias where pai = $pai");

  echo "<ul>";
  while ($filho=mysql_fetch_array($q))
        {
                echo "<ul><li>{$filho["nome"]}</li></ul>";
                printSubmenus($filho["id"]);
        }
echo "</ul>";
}
printSubmenus(0);
?>

E agradeço bastante ao softclean, obrigadão!!!  :D

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Só um pequeno detalhe, essa última chamada que tens aí à função printSubmenus não está lá a fazer mais nada senão uma query adicional que não te retorna nada na bd, pelo que podes perfeitamente eliminá-la.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Só um pequeno detalhe, essa última chamada que tens aí à função printSubmenus não está lá a fazer mais nada senão uma query adicional que não te retorna nada na bd, pelo que podes perfeitamente eliminá-la.

Na verdade sem essa linha o código não faz nada...  :D

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