[PHP & MySQL] 뎁스 제한없는 메뉴 출력하기
Posted at 2012.08.13 21:28 | Posted in 프로그래밍3단 메뉴, 5단 메뉴, 10단 메뉴 등 하위 메뉴를 개수 제한 없이 출력하는 메뉴 출력 함수를 작성해 볼것이다.
먼저, 데이터베이스 테이블 구조는 다음과 같이 짜준다.
mysql> describe links; +-------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+---------------------+------+-----+---------+----------------+ | idx | tinyint(3) unsigned | NO | PRI | NULL | auto_increment | | pid | tinyint(3) unsigned | NO | MUL | 0 | | | menu | tinyint(3) unsigned | NO | MUL | 0 | | | title | varchar(100) | NO | | NULL | | | url | varchar(100) | NO | | NULL | | | ord | tinyint(3) unsigned | NO | MUL | 1 | | +-------+---------------------+------+-----+---------+----------------+ 6 rows in set (0.00 sec)
메뉴(카테고리) 정보가 저장되어있는 links 테이블의 레코드는 다음과 같다
mysql> select * from links; +-----+-----+------+-----------------------------+---------------------------+-----+ | idx | pid | menu | title | url | ord | +-----+-----+------+-----------------------------+---------------------------+-----+ | 1 | 0 | 0 | 홈 | / | 1 | | 2 | 0 | 0 | 블로그 | http://blog.bloodcat.com/ | 2 | | 3 | 0 | 0 | 개발 | /dev/ | 3 | | 4 | 0 | 0 | 기타 | # | 4 | | 5 | 4 | 0 | osu! 비트맵 다운로더 | /osu/ | 1 | +-----+-----+------+-----------------------------+---------------------------+-----+ 5 rows in set (0.00 sec)
PHP에 다음 소스를 작성한다.
<?php function doMenu($menu, $pid) { $query = mysql_query('select * from links where pid = '.$pid.' and menu = '.$menu.' order by ord'); $links = array(); while(($links[] = mysql_fetch_array($query)) || array_pop($links)); if($links) { ?><ul><?php foreach($links as $i) { ?><li><a href="<?=$i['url'];?>"><?=$i['title'];?></a><?php doMenu($menu, $i['idx']); ?></li><?php } ?></ul><?php } } ?>
작성한 소스를 <?=doMenu(0, 0)?>처럼 호출하면 다음과 같은 소스를 반환한다
<ul> <li><a href="/">홈</a></li> <li><a href="http://blog.bloodcat.com/">블로그</a></li> <li><a href="/dev/">개발</a></li> <li><a href="#">기타</a> <ul> <li><a href="/osu/">osu! 비트맵 다운로더</a></li> </ul> </li> </ul>
!. 하위 메뉴까지 완벽하게 출력하는 메뉴 출력함수가 완성되었다
[속도 대폭 상승]데이터베이스와 한번만 통신하는 클래스
class Menu { public static function aio($menu, $pid) { $src = static::get($menu); static::display($src, $pid); } public static function get($menu) { global $db; $query = $db->query('select idx, url, title, pid from '.DB_ID.'links where menu = '.$menu.' order by ord'); $links = array(); while(($links[] = $query->fetch_row()) || array_pop($links)); return $links; } public static function display($src, $pid) { $todo = array(); foreach($src as $key=>$i) if($i[3] == $pid) { $todo[] = array($i[0], $i[1], $i[2]); unset($src[$key]); } if(!is_null($todo[0])) { ?><ul><?php foreach($todo as $i) { ?><li><a href="<?=$i[1]?>"><?=$i[2]?></a><?php static::display($src, $i[0]); } ?></ul><?php } } }
사용은 Menu::aio(0, 0);처럼~