Um erro muito comum em modelagem de dados concerne a sistemas de categorias e subcategorias. Muitos não sabem como modelar o banco de dados, criam diversas tabelas e acabam complicando o que é simples.
Mostrarei um forma muito simples de como armazenar essas informações num banco de dados e como exibi-las na tela, na forma de lista, técnica muito utilizada para construção de menus.
Vamos à modelagem, primeiramente.
Teremos apenas uma tabela. Esta é a estrutura dela:
(usarei MySQL neste artigo, mas a lógica da modelagem independe do SGBD usado)
CREATE TABLE categorias( id INT(5) UNSIGNED NOT NULL AUTO_INCREMENT, id_pai INT(5) UNSIGNED NOT NULL, nome VARCHAR(20) NOT NULL, PRIMARY KEY (id) ) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; |
Vamos popular a tabela da seguinte forma:
INSERT INTO categorias(id, id_pai, nome) VALUES (1, 0, 'A Empresa'), (2, 1, 'Sobre Nós'), (3, 1, 'Objetivos'), (4, 3, 'Objetivo dos nossos clientes'), (5, 0, 'Contato'), (6, 0, 'Produtos'); |
Obteremos a seguinte tabela:
mysql> select * from categorias; +----+--------+----------------------+ | id | id_pai | nome | +----+--------+----------------------+ | 1 | 0 | A Empresa | | 2 | 1 | Sobre Nós | | 3 | 1 | Objetivos | | 4 | 3 | Objetivo dos nossos | | 5 | 0 | Contato | | 6 | 0 | Produtos | +----+--------+----------------------+ 6 rows in set (0,00 sec) |
Nessa estrutura, temos três seções principais: “A Empresa”, “Contato” e “Produtos”. As categorias “Sobre Nós” e “Objetivos” são subcategorias de “A Empresa”. E “Objetivos dos nossos clientes” é subcategoria de “Objetivos”, que, por sua vez, é subcategoria de “A Empresa”, como citado anteriormente.
Vamos fazer uma seleção dessas informações e colocá-las num arrray, como o exibido abaixo.
// array que conterá as categorias $cats = array(); $mysqli = new mysqli( 'localhost', 'user', 'senha', 'bancoDeDados' ); $sql = 'SELECT id, id_pai, nome FROM categorias'; $exec = $mysqli->query( $sql ) or exit( $mysqli->error ); $i = 1; while ( $f = $exec->fetch_object() ) { $cats[$i]['id'] = $f->id; $cats[$i]['id_pai'] = $f->id_pai; $cats[$i]['nome'] = $f->nome; $i++; } |
Obteremos um array como o exibido abaixo:
$cats[1]['id_pai'] = 0; $cats[1]['nome'] = 'A Empresa'; $cats[2]['id_pai'] = 1; $cats[2]['nome'] = 'Sobre Nós'; $cats[3]['id_pai'] = 1; $cats[3]['nome'] = 'Objetivo'; $cats[4]['id_pai'] = 3; $cats[4]['nome'] = 'Objetivos dos Nossos Clientes'; $cats[5]['id_pai'] = 0; $cats[5]['nome'] = 'Contato'; $cats[6]['id_pai'] = 0; $cats[6]['nome'] = 'Produtos'; |
Note que o array não começou em zero. Os índices do array são os ID’s das categorias no banco de dados. Se começasse em zero, causaria conflito com o id_pai, que é zero para categorias principais.
Agora postarei uma função simples em PHP que montará o menu completo.
/** * Função que monta o menu com as categorias e subcategorias. * @param id_pai ID da categoria pai cujas subcategorias serão buscadas. * @param ArrayCats Array com as categorias do menu. */ function montaMenu( $id_pai, $arrayCats ) { // calcula o número de índices do array $catsSize = count( $arrayCats ); echo "<ul>"; for ( $i = 1; $i <= $catsSize; $i++ ) { if ( $arrayCats[ $i ]['id_pai'] == $id_pai ) { echo "<li>"; echo $arrayCats[ $i ]['nome']; // busca as subcategorias da categoria atual montaMenu( $arrayCats[ $i ]['id'], $arrayCats ); echo "</li>"; } } echo "</ul>"; } |
Você pode usar duas variáveis globais, se quiser: o array das categorias e a variável $catsSize. Isso reduz o processamento, uma vez que a função count() seria chamada apenas uma vez. Porém, para projetos grandes, com diversos menus, essa prática não seria bem-vinda.
Para exibir o menu, basta chamar a função da seguinte forma:
montaMenu( 0, $cats ); |
Ela começará buscando as categorias principais (id_pai = 0) e depois buscará por cada subcategoria.
Roberto Beraldo
Latest posts by Roberto Beraldo (see all)
- Não Tenha Preguiça de Ler! - 25/04/2016
- Como Atualizar Scripts PHP de MySQL Para MySQLi - 29/10/2015
- Como usar PDO com banco de dados MySQL - 10/09/2015