Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Bom dia a todos.
Segue minha estrutura de banco:
--
-- Estrutura da tabela gc_cat_prdts
--
CREATE TABLE IF NOT EXISTS `gc_cat_prdts` (
`CT_IdCat` int(10) NOT NULL AUTO_INCREMENT,
`CT_IdParent` int(10) DEFAULT '0',
`CT_Nom` varchar(100) NOT NULL,
PRIMARY KEY (`CT_IdCat`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Categorias' AUTO_INCREMENT=71 ;
--
-- Extraindo dados da tabela gc_cat_prdts
--
INSERT INTO gc_cat_prdts (CT_IdCat, CT_IdParent, CT_Nom) VALUES
(1, 0, 'Temas e Decorações'),
(2, 0, 'Serviços'),
(3, 0, 'Cardápio'),
(4, 3, 'Bolos'),
(5, 3, 'Bebidas'),
(6, 3, 'Salgados'),
(7, 3, 'Doces e Guloseimas'),
(20, 1, 'Festa Teen'),
(21, 1, 'Adulto'),
(22, 1, 'Festa Lanche'),
(23, 1, 'Infantil'),
(24, 1, 'Temas Terceirizados'),
(25, 1, 'Antigos'),
(26, 1, 'Femininos'),
(28, 1, 'Masculinos'),
(29, 1, 'Decoração do Salão'),
(30, 1, 'Unissex'),
(32, 1, 'Formatura'),
(33, 1, 'Times'),
(35, 2, 'Vídeo Fotos'),
(36, 2, 'Enfeites de Mesa'),
(37, 2, 'Convites'),
(38, 2, 'Lembrancinhas'),
(63, 1, 'Festa Especial'),
(64, 22, 'Básica'),
(65, 22, 'Especial'),
(66, 22, 'Completa'),
(67, 37, 'Personalizados'),
(68, 37, 'Especiais'),
(69, 68, 'Com Envelope'),
(70, 68, 'Sem Envelope');
Sempre que busco por multi-categorias me deparo com algo: "Recursividade".
Inclusive eu postei uma vez um código de multi-categorias porém ele era recursivo. Quando ele foi apagado eu pensei que fosse por isso, mas não recebi nenhuma notificação informando o porquê meu post tinha sido deletado.
Bom, feita minha introdução, formulo minha questão:
Alguém tem para postar algum código de multi-categorias que não seja recursivo que liste as categorias do banco acima?
E quero montar uma estrutura assim:
<ul>
<li>Temas e Decorações
<ul>
<li>Adulto</li>
<li>Antigos</li>
<li>Decoração do Salão</li>
<li>Femininos</li>
<li>Festa Especial</li>
<li>Festa Lanche
<ul>
<li>Básica</li>
<li>Completa</li>
<li>Especial</li>
</ul>
</li>
<li>Festa Teen</li>
<li>Formatura</li>
<li>Infantil</li>
<li>Masculinos</li>
<li>Temas Terceirizados</li>
<li>Times</li>
<li>Unissex</li>
</ul>
</li>
<li>Serviços
<ul>
<li>Convites
<ul>
<li>Especiais
<ul>
<li>Com Envelope</li>
<li>Sem Envelope</li>
</ul>
</li>
<li>Personalizados</li>
</ul>
</li>
<li>Enfeites de Mesa</li>
<li>Lembrancinhas</li>
<li>Vídeo Fotos</li>
</ul>
</li>
<li>Cardápio
<ul>
<li>Bebidas</li>
<li>Bolos</li>
<li>Doces e Guloseimas</li>
<li>Salgados</li>
</ul>
</li>
</ul>
Esta seria a representação do banco exibido.
Obrigado
>
Veja se isso te ajuda.
Tem uma versão procedural e outra orientada a objetos.
Bruno, a procedural é recursiva e a orientada a objeto dá esse erro: "Catchable fatal error: Object of class Menu could not be converted to string in "
Uma pergunta: Existe alguma orientação quanto ao uso de uma função recursiva?
pois tenho uma função de menu que uso que é recursiva e que me atende bastante, porém não sei o quanto esse recurso é aconselhável.
Se não houver problemas continuo com a minha antiga função:
// Função gerar menu, parentId 0 é a raiz
function GeraMenu($parent, $menuData)
{
$html = "";
if (isset($menuData['parents'][$parent]))
{
$html .= "<ul>\n";
foreach ($menuData['parents'][$parent] as $itemId)
{
if(!isset($menuData['parents'][$itemId]))
{
$html .= "<li>\n <a href='".$menuData['items'][$itemId]['CT_IdCat']."'>".$menuData['items'][$itemId]['CT_Nom']."</a>\n </li>\n";
}
if(isset($menuData['parents'][$itemId]))
{
$html .= "<li>\n <a href='".$menuData['items'][$itemId]['CT_IdCat']."' >".$menuData['items'][$itemId]['CT_Nom']."</a> \n";
$html .= GeraMenu($itemId, $menuData);
$html .= "</li>\n";
}
}
$html .= "</ul>\n";
}
return $html;
}
/**
* Busca na tabela de categorias
*/
$sql = "
SELECT CT_IdCat, CT_IdParent, CT_Nom, CT_Ordm
FROM gc_cat_prdts
ORDER BY CT_IdParent ASC, CT_Ordm ASC, CT_Nom ASC
";
$result = $mysqli->query($sql);
$linhas = $result->num_rows;
// Criar uma matriz multidimensional contendo uma lista de itens e os pais
$menuData = array(
'items' => array(),
'parents' => array()
);
/**
* percorre o objeto mysqli_result retornado (array associativo)
* associative array
*/
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
$idCat = $row['CT_IdCat'];
$idParent = $row['CT_IdParent'];
$nomeCat = $row['CT_Nom'];
// Cria entrada em itens de menu atual matriz com i id item. $menuData['items'][1]
$menuData['items'][$row['CT_IdCat']] = $row;
// Cria entrada em pais matriz. Pais matriz contém uma lista de todos os itens com os filhos
$menuData['parents'][$row['CT_IdParent']][] = $row['CT_IdCat'];
}
/**
* Função para montar o menu
* Para chamar o menu simplesmente executar a função com o nível que você deseja exibir
*/
$Categorias = GeraMenu(0, $menuData);
Quase perdi seu tópico...
Recursão deve ser evitada sempre que possível, mas principalmente quando sua lógica for demasiadamente complexa e o array de entrada tenha muitas dimensões aninhadas. E ainda pior quando cada nova dimensão tivermuitas entradas.
Isso porque a forma mais básica de uma recursão é iterar a primeira dimensão e verificar se o valor corrente é um array. Se for, invoca a própria função, informando o novo valor:
function foo( $bar ) {
foreach( $bar as $b ) {
if( is_array( $b ) ) {
foo( $b );
} else {
// Faz alguma coisa com $b
}
}
// Retorna algo (ou não)
}
E quando a lógica é complexa, a carga de memória e processamento aumenta a níveis alarmantes.
Alguns meses atrás eu esbarrei numa forma de "recursão sem recursão" onde referências eram utilizadas. Como eu nunca mexi a fundo com referências, não entendi muito bem, mas me pareceu uma alternativa bastante viável.
Eu encontrei acidentalmente um artigo que explica o motivo de os arrays serem grandes e pesados. Assim que possível eu pretendo traduzí-lo, mas se quiser dar uma olhada...
Veja se isso te ajuda.
Tem uma versão procedural e outra orientada a objetos.