Menu đa cấp - Đệ qui 2008-03-15 01:26:49
Thấy thỉnh thoảng anh em lại gặp vấn đề về menu đa cấp và viết đệ qui, mấy hôm nay viết shopping cart nên có chút kinh nghiệm share với anh em
Về database, tạo menu có cấu trúc đơn giản như sau:
table categories: id,parentid,title
id parentid title
1 0 Menu 1
2 0 Menu 2
3 1 Menu 1.0
4 1 Menu 1.1
5 3 Menu 1.0.0
6 3 Menu 1.0.1
yêu cầu khi tạo thành menu phải có dạng
Menu 1
Menu 1.0
Menu 1.0.0
Menu 1.0.1
Menu 1.1
Menu 2
Phần code:
<?php
function Menu($parentid = 0,$space = '--', $trees = NULL){
if(!$trees) $trees = array();
$sql = mysql_query("SELECT * FROM php_category WHERE cat_parentid = ".intval($parentid));
while($rs = mysql_fetch_assoc($sql)){
$trees[] = array('id'=>$rs['cat_id'],'title'=>$space.$rs['cat_title']);
$trees = Menu($rs['cat_id'],$space.'--',$trees);
}
return $trees;
}
$Menu = Menu(0);
$str = '';
foreach($Menu as $k=>$rs) $str .= '<a href="#menu='.$rs['id'].'">'.$rs['title'].'</a>';
echo $str;
?>
Ngoài ra hàm này có thể hiển thị được cây thư mục của 1 category bất kỳ, ví dụ: $Menu = Menu(3) sẽ hiển thị cây thư mục của các menu con của category có id = 3
Chúc thành công
Tra loi 37 comment(s) 2008-03-15 01:26:49
Quan Tran Anh 2008-03-15 10:18:12
Code của ông TG dùng quá nhiều Query rùi, ko tối ưu.
Tui gửi mọi người code của mình, mọi người tham khảo nhe.
Giả sử $aCats là 1 array được lấy về bởi câu lệnh : SELECT * FROM tbl_categories chẳng hạn, nó sẽ là một mảng gồm các row được lấy theo kiểu :
<?php
while($row = mysql_fetch_array($iResult)){
$aCats[] = $row;
}
?>
===============================
<?php
$aCats = array(
array(1,"Computers",0), // ID, Cat name,Cat parent ID
array(2,"Electronics",0),
array(3,"Laptop",1),
array(4,"Mp3 Players",2),
array(5,"Desktop",1),
array(6,"iPod",4),
array(7,"Dell",3),
array(8,"TV",0)
);
$sMenu = Menu(0,$aCats);
echo $sMenu;
function Menu($parentid,$aCats,$res = '',$sep = ''){
foreach($aCats as $v){
if($v[2] == $parentid){
$re = $sep."<a href=\"category.php?id={$v[0]}\">{$v[1]}</a><br />";
$res.=Menu($v[0],$aCats,$re,$sep."--");
}
}
return $res;
}
?>
Tra loi
TG 2008-03-15 03:49:24
Tra loi
cocbay 2008-03-15 04:35:25
Nếu menu mà cố định (chỉ vài cái submenu) thì làm HTML cho "phẻ" nhe...
Tra loi
Quan Tran Anh 2008-03-17 10:18:00
Lượm lặt gì :D
Khó nhất là sinh ra cái menu dạng di chuột vào, xổ ra 1 cách tự động :D Tui lười nên chả viết :D Cty có mấy người chuyên làm việc này hay lắm :D
Tra loi
uoon 2008-03-17 10:39:43
code PHP và SQL thiết kế làm sao em không biết, nhưng có cái này:
<?php
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><title>Nhan Cu Vi Bat Thien</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="expires" content="0">
<style type="text/css">
.H-Menu {
border-bottom: 1px solid orange;
background-color: #abcdef;
height: 28px;
}
.H-Menu .SMenu1 {
position: relative;
cursor: pointer;
height: 23px;
float: left;
background-color: #9b1a00;
color: white;
padding: 0px 10px 0px 10px;
margin-top: 4px;
margin-right: 3px;
border: 1px solid green;
border-bottom: none;
}
.H-Menu .MOver {
color: black;
padding-top: 1px;
background-color: white;
}
.H-Menu .OClick {
background-color: yellow;
}
.H-Menu .V-Menu1 {
color: white;
width: 149px;
border: 1px solid green;
background-color: #9b1a00;
display: none;
}
.V-Menu1 .SMenu2, .V-Menu2 .SMenu3, .V-Menu3 .SMenu4 {
position: relative;
padding: 0px 10px 0px 10px;
}
.V-Menu1 .MOver {
color: black;
background-color: white;
}
.SMenu2 .V-Menu2, .SMenu3 .V-Menu3{
color: white;
position: absolute;
top: 0px;
left: 149px;
border: 1px solid green;
width: 149px;
background-color: #9b1a00;
display: none;
}
.H-Menu .MOver .V-Menu1, .V-Menu1 .MOver .V-Menu2, .V-Menu2 .MOver .V-Menu3 {
display: block;
}
</style>
</head>
<body>
<div style="position: relative; height: 0px;">
<div class="H-Menu">
<div class="SMenu1" onmouseover="this.className='SMenu1 MOver'" onmouseout="this.className='SMenu1'">
<div>1-Menu</div>
</div>
<div class="SMenu1" onmouseover="this.className='SMenu1 MOver'" onmouseout="this.className='SMenu1'">
<div>1-Menu</div>
</div>
<div class="SMenu1" onmouseover="this.className='SMenu1 MOver'" onmouseout="this.className='SMenu1'">
<div style="position: absolute; height: 0px; width: 0px; top: 23px; left: -1px;">
<div class="V-Menu1">
<div class="SMenu2" onmouseover="this.className='SMenu2 MOver'" onmouseout="this.className='SMenu2'">
<div>2-Menu</div>
</div>
<div class="SMenu2" onmouseover="this.className='SMenu2 MOver'" onmouseout="this.className='SMenu2'">
<div>2-Menu</div>
</div>
<div class="SMenu2" onmouseover="this.className='SMenu2 MOver'" onmouseout="this.className='SMenu2'">
<div class="V-Menu2">
<div class="SMenu3" onmouseover="this.className='SMenu3 MOver'" onmouseout="this.className='SMenu3'">
<div>3-Menu</div>
</div>
<div class="SMenu3" onmouseover="this.className='SMenu3 MOver'" onmouseout="this.className='SMenu3'">
<div>3-Menu</div>
</div>
<div class="SMenu3" onmouseover="this.className='SMenu3 MOver'" onmouseout="this.className='SMenu3'">
<div class="V-Menu3">
<div class="SMenu4" onmouseover="this.className='SMenu4 MOver'" onmouseout="this.className='SMenu4'">
<div>4-Menu</div>
</div>
<div class="SMenu4" onmouseover="this.className='SMenu4 MOver'" onmouseout="this.className='SMenu4'">
<div>4-Menu</div>
</div>
<div class="SMenu4" onmouseover="this.className='SMenu4 MOver'" onmouseout="this.className='SMenu4'">
<div>4-Menu</div>
</div>
<div class="SMenu4" onmouseover="this.className='SMenu4 MOver'" onmouseout="this.className='SMenu4'">
<div>4-Menu</div>
</div>
</div>
<div>3-Menu</div>
</div>
<div class="SMenu3" onmouseover="this.className='SMenu3 MOver'" onmouseout="this.className='SMenu3'">
<div>3-Menu</div>
</div>
</div>
<div>2-Menu</div>
</div>
<div class="SMenu2" onmouseover="this.className='SMenu2 MOver'" onmouseout="this.className='SMenu2'">
<div>2-Menu</div>
</div>
</div>
</div>
<div>1-Menu</div>
</div>
<div class="SMenu1" onmouseover="this.className='SMenu1 MOver'" onmouseout="this.className='SMenu1'">
<div>1-Menu</div>
</div>
</div>
</div>
</body>
</html>
?>
Kỹ thuật này do em mới sáng tạo ra :D. Chẳng biết đã xuất hiện ở đâu chưa, nhưng với mình là mới.
Tra loi
Quan Tran Anh 2008-03-17 10:51:29
Tra loi
cocbay 2008-03-17 11:01:11
Lượm lặt gì :D
Bạn không thấy mình viết:
Mình là dân Sài Gòn, quận 8 nữa, hơi gian hồ tí, nên bạn dùng từ "lạy ông, lại bà hay lại ngài" nghe nó sao sao, hơi bị sốc... Bít là Quan Anh bro, nhưng dùng từ không hay lắm :(
Tra loi
Quan Tran Anh 2008-03-17 11:25:11
Sorry nếu phạm húy :) Vì tui ở HN, nên ko bít trong SG hay nói như nào cả
Sorry, blame it on me :)
Tra loi
Nguyen Duc 2008-04-21 02:43:43
ai viet duoc cho xin voi huhu....
Tra loi
Vy Quang Hoa 2008-05-05 08:59:58
Y!M :vpp_hat
hoặc lên www.weldvina.com/rum mà download, ko cần có bài viết, làm thành viên phát là download bao cao su luôn !
Tra loi
Vy Quang Hòa 2008-05-05 09:05:52
Tra loi
changtraingheo 2008-05-06 11:16:29
Tra loi
changtraingheo 2008-05-06 11:16:48
Tra loi
gaulucky92 2008-05-06 06:17:06
Tra loi
changtraingheo 2008-05-06 09:08:35
- Còn về Pro thì hiện tại trong mắt mình có 2 thần tượng làm chung ở cty, nghỉ roài. Ko tham gia vào bất cứ forum nào về IT hết, mà từ MySQL, Javascript, CSS, PHP, SQL Server ... xin lỗi luôn , thuộc dạng hàng khủng ... :D
Tra loi
web20vn.com 2008-05-07 12:19:34
Tra loi
Vy Quang Hòa 2008-05-07 10:04:29
Tra loi
gaulucky92 2008-05-07 12:40:06
- Còn về Pro thì hiện tại trong mắt mình có 2 thần tượng làm chung ở cty, nghỉ roài. Ko tham gia vào bất cứ forum nào về IT hết, mà từ MySQL, Javascript, CSS, PHP, SQL Server ... xin lỗi luôn , thuộc dạng hàng khủng ... :D
Ôi ước gì có máy hút não nhỉ 8-> rút hết não của 2 ông đó ra là em thành pro =))
em cũng gặp chuyện help tương tự thôi :D lâu lâu check mail có người gửi hỏi han tùm lum, có khi hỏi host, lúc thì domain,... có người nhờ viết web dùm nữa! :-S ko lẽ từ chối kì quá, cho nên làm đại 1 trang html kèm theo cái code php để tạo random image rồi đưa ;)) xấu quắc :(
Ko hỏi chuyện web thì lại hỏi chuyện game (chắc tại thấy em spam trên 4rum game nhiều quá nên tưởng pro =))), tự nhiên "Ban oi ban chi cho minh choi chien quoc nha, minh la nguoi moi ko biet gi het.." ==> pó tay :-??
Tra loi
gaulucky92 2008-05-07 12:44:55
@Vy Quang Hoa: giao diện đẹp nhờ có thêm hình ảnh :D còn cái trang game của bác em nhìn thấy cũng đơn giản mà :D 1 câu query gọi thông tin game ra và sắp xếp cho nó... dùng div với float:left là OK ^^
Còn phần skin đổi màu tương ứng, theo em nghĩ nó kiểu như vầy:
Trong CSS thì tạo 4 cái:
hanhdong {
...
}
thethao {
...
}
nhapvai {
...
}
codien {
...
}
Như vậy với mỗi page có giá trị khác nhau thì div mang 1 class tương ứng. :D
Tra loi
Vy Quang Hòa 2008-05-13 03:24:51
while($row = mysql_fetch_array($iResult)){
$aCats[] = $row;
}
?>
===============================
<?php
$aCats = array(
array(1,"Computers",0), // ID, Cat name,Cat parent ID
array(2,"Electronics",0),
array(3,"Laptop",1),
array(4,"Mp3 Players",2),
array(5,"Desktop",1),
array(6,"iPod",4),
array(7,"Dell",3),
array(8,"TV",0)
);
$sMenu = Menu(0,$aCats);
echo $sMenu;
function Menu($parentid,$aCats,$res = '',$sep = ''){
foreach($aCats as $v){
if($v[2] == $parentid){
$re = $sep."<a href=\"category.php?id={$v[0]}\">{$v[1]}</a><br />";
$res.=Menu($v[0],$aCats,$re,$sep."--");
}
}
return $res;
}
?>
Cho hỏi code nh] của bác này rồi, thì làm sao để phân biệt đươck chỗ nào là code của menu cấp cao hơn để làm cho nó khi click vào menu cha thì xổ ra menu con,
$res.=Menu($v[0],$aCats,$re,$sep."--");
Giống nhau tất nh] vậy chẳng biết chỗ nào, bác nào giúp em cái, và CSDL của menu này thì thiết kế kiểu gì nhỉ !
Tra loi
akaa 2008-05-20 02:36:41
Tra loi
MEO 2008-05-25 05:52:49
Tra loi
babyblue 2008-05-29 09:04:13
đệ quy là hàm gọi lại chính bản thân hàm đó.
Đối với mình thì khi lập trình tránh dùng đệ quy là tốt nhất, vì đệ quy đơn giản về mã nguồn nhưng lại ảnh hưởng đến tốc độ.
Đối với menu đa cấp >=2 thì đệ quy tỏ ra thích hợp nhưng nên chạy một lần khi thay đổi dữ liệu thôi, sau đó ghi ra file dưới dạng xml chẳng hạn, sẽ tối ưu được tốc độ.
Bởi vì nếu để nguyên cái code đó chạy mỗi khi có 1 trình duyệt gởi request thì sao nếu có khoảng 10.000 lượt truy cập một lần.
Trên đây chỉ là ý kiến bản thân.
Em không phải dân IT, có sai xin đừng chấp nhé các PRO
Tra loi
BCC 2008-07-26 01:05:20
Đệ quy của 2 PRO rất hay, nhưng để xử lý các topic liên quan đến từng Category ngẫu nhiên thì em còn đang băn khoăn (Ví như: khi vào Parent thì liệt kê toàn bộ topic của Parent, còn khi vào Child thì chỉ liệt kê của nó). Xin các huynh chỉ giáo!
Tra loi
TG 2008-07-26 09:29:11
Tra loi
BCC 2008-07-26 02:48:05
Nếu có thể, các huynh chi tiết luôn cả code cho em thì tốt.
Very thanks!
Tra loi
TG 2008-07-27 09:47:56
Tra loi
NDT 2008-08-20 01:15:34
http://dev.mysql.com/tech-resources/articles/hierarchical-data.html
Cũng có khá nhiều topic về cái này trên mạng, chúc mọi người vui!
Tra loi
TG 2008-08-20 08:39:51
Tra loi
Ngoc 2008-09-05 08:13:46
cái code của TG ngộ thiệt nó kg chạy với mysqli, để kết nối bằng mysql bình thường thì nó chạy mặc dù kg có gì sai. Sau khi test nó chỉ chạy trên localhost còn khi uplen server thì nó kg chịu chạy thế mới bực mình.
Có ai có kinh nghiệm về Pear TreeMenu kg vậy thì giúp mình với mình làm đúng theo nó thì nó báo lổi fantal object
<?php
// include HTML_TreeMenu class
include "HTML/TreeMenu.php";
// initialize menu object
$root = new HTML_TreeMenu();
// create the first node (node id 1)
$node1 = new HTML_TreeNode(array("text" => "Sitemap", "link" => ""));
$root->addItem($node1);
// open connection
$connection = mysql_connect("localhost", "root", "")or die ("Unable to connect!");
// select database
mysql_select_db("docteurdiscount") or die ("Unable to select database!");
// create query
$query = "SELECT * FROM drdiscount_category_new ORDER BY cat_parentid";
// execute query
$result = mysql_query($query)or die ("Error in query: $query. " . mysql_error());
// dynamically create nodes for each parent/child combination
// attach each child to its parent
if (mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_assoc($result)) {
$parentObjName = "node" . $row['cat_parentid'];
$childObjName = "node" . $row['cat_id'];
$$childObjName = new HTML_TreeNode(array("text" => $row["cat_name"], "link" => ""));
$$parentObjName->addItem($$childObjName);
}
}
// free result set memory
mysql_free_result($result);
// close connection
mysql_close($connection);
?>
<html>
<head>
<!-- link in the JavaScript code for expanding/collapsing the tree -->
<script src="TreeMenu.js" language="JavaScript"type="text/javascript"></script>
</head>
<body>
<?php
// initialize menu interface
// set options: path for tree images
// frame to load click targets
$menu = new HTML_TreeMenu_DHTML($root,array("linkTarget" => "rhframe", "images" => "HTML/images/"));
// print menu tree
$menu->printMenu();
?>
</body>
</html>
nó báo lỗi ở dòng này
$$parentObjName->addItem($$childObjName);
mình kiểm tra đi kiểm tra lại thì thấy kg có gì sai cả thế mà nó kg ra.
down thư viện pear về xài cái example của nó cực ấn tượng
http://pear.php.net/package/HTML_TreeMenu/download
làm được nhiều việc hay lắm
Tra loi
nhuynhduc 2008-10-25 12:38:19
Tra loi
Bút chì đầu đỏ 2008-11-07 01:10:34
chung quy lại là các bác spam là nhiều bình luận thì ít ! đánh giá cũng ít luôn. Không buồn ý kiến nhiều. E cũng không cần khen chê! bác nào thấy sài được thì sài! em gộp cả 2 cách viết của 2 bác trên cùng để sài! ứng dụng cho cả X-Templates và smarty. Good luck
<?php
while($rows = mysql_fetch_array($thucthi))
{
$aCats[] = $rows;
}
function Menu($parentid,$aCats,$sep='',$cols = array()){
foreach($aCats as $v){
if($v["id_sub"] == $parentid){
$cols[$v["id"]]['id'] = $v["id"];
$cols[$v["id"]]['title'] = $sep.$v["title"];
$cols = Menu($v["id"],$aCats,$sep."--",$cols);
}
}
return $cols;
}
$sMenu = Menu(0,$aCats);
print_r($sMenu);
?>
Tra loi
duc1983 2008-11-21 10:11:33
Tra loi
TG 2009-11-26 04:27:04
Đây là đoạn code để xuất ra menu đa cấp dưới dạng ul, li
<?php
$sql = mysql_query("SELECT * FROM categories ORDER BY parentid");
$data = array();
while($rs = mysql_fetch_assoc($sql)){
$data[$rs['parentid']][] = $rs;
}
function data2xml($data,$parent = 0,$parents = '',$sep = '/',$dir,$ext = ''){
$str = '';
if(count($data[$parent])){
$str .= '<ul>';
if($parents) $parents .= $sep.$parent;
else $parents = $dir;
foreach($data[$parent] as $rs){
$str .= '<li><a href="'.$parents.$sep.$rs['id'].$ext.'">'.$rs['title'].'</a></li>';
$str .= data2xml($data,$rs['id'],$parents,$sep,$dir,$ext);
}
$str .= '</ul>';
}
return $str;
}
echo data2xml($data,0,'','-','./cat','.html');
?>
Lúc này sẽ xuất cho bạn 1 menu bằng ul,li. bạn chỉ cần tìm script tạo menu gắn vào là có menu như mong muốn
Tra loi
khách 2010-01-22 09:44:40
Tra loi
Y kien