[英]Simple PHP Menu with MPTTA Hierarchy
我正在嘗試使用 PHP 創建一個簡單的無序列表菜單。 該列表由 MySQL 填充。 我很難找到符合我特定需求的說明。
要求
代碼:
CREATE TABLE IF NOT EXISTS `maj_topmenu` (
`menu_id` int(11) NOT NULL auto_increment,
`menu_title` varchar(100) NOT NULL default '',
`menu_url` varchar(200) NOT NULL default '',
`menu_level` int(10) NOT NULL default '0',
`parent_id` int(11) NOT NULL default '0',
`lft` int(10) NOT NULL,
`rgt` int(10) NOT NULL,
`displayorder` int(11) default NULL,
PRIMARY KEY (`menu_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
INSERT INTO `maj_topmenu` (`menu_id`, `menu_title`, `menu_url`, `menu_level`, `parent_id`, `lft`, `rgt`, `displayorder`) VALUES
(1, 'Home', '/home', 0, 0, 1, 2, 0),
(2, 'About Us', '/about', 0, 0, 5, 10, 10),
(3, 'News', '/news', 0, 0, 3, 4, 5),
(4, 'Blogs', '/viewblog', 0, 0, 11, 12, 15),
(5, 'Contact Us', '/contact', 0, 0, 13, 14, 20),
(6, 'Sub Menu 1', '/link1', 1, 2, 6, 9, 0),
(7, 'Sub Menu 2', '/link2', 2, 6, 7, 8, 0);
PHP 零件
$topmenu = '';
$nodes=array();
$nlbr = "\n";
// Now, retrieve all descendants of the $root node
$sql="SELECT n.menu_title, n.menu_title, n.menu_url, n.parent_id, n.lft, n.rgt FROM maj_topmenu AS n, maj_topmenu AS p WHERE n.lft BETWEEN p.lft AND p.rgt AND p.parent_id = '0' ORDER BY n.lft";
$result = mysql_query($sql) or die(mysql_error());
$topmenu .= '<ul>' . $nlbr;
while ($row = mysql_fetch_array($result))
{
if ( ($row['rgt'] - $row['lft']) == 1 )
{
// No child elements
if (sizeof($nodes) == 0)
{
// We're at the top with no children
$topmenu .= '<li>'.$row['lft'].' <a href="'.$row['menu_url'].'">'.$row['menu_title'].'</a> '.$row['rgt'].'</li>' . $nlbr;
continue;
}
else
{
// We're in the middle with no children; We'll need to end at least one branch
$topmenu .= '<li>'.$row['lft'].' <a href="'.$row['menu_url'].'">'.$row['menu_title'].'</a> '.$row['rgt'].'</li>' . $nlbr;
while ( ($row['rgt'] + 1) - end($nodes) == 0 )
{
$topmenu .= '</ul>' . $nlbr;
array_pop($nodes);
}
continue;
}
}
else
{
// Start a new branch
$topmenu .= '<li>'.$row['lft'].' <a href="'.$row['menu_url'].'">'.$row['menu_title'].'</a> '.$row['rgt'].'</li>' . $nlbr;
$topmenu .= '<ul>' . $nlbr;
// End leaf at this point later
$nodes[] = $row['rgt'];
}
}
$topmenu .= '</ul>';
我遇到的問題是循環沒有在適當的地方結束節點。 如果我在第 3 級分支,它可能會結束太多或太少的列表。
該腳本稍后可能用於廣泛的層次結構數據,這就是我為此使用 MPTTA 的原因,並且我試圖避免必須在多個級別上進行查詢。
我已經編輯了這個答案以改進它。
它使用一個 sql 查詢而不是三個
它使用“order by”,因此您可以確定預購行程受到尊重,這意味着您只能通過編輯級別和順序來定義遍歷路徑,將級別視為自上而下移動,將順序視為從左到右移動。
..list item tag..你的意思是1.1、1.2等……如果是這樣,那就完成了。
..節點開始和結束的地方...您的意思是參考級別已完全顯示,而其他級別則沒有(它們很接近),如果是這樣的話,沒關系。
..self-reference ...如果您的意思是function自稱,我真的看不出這是在哪里發生的(包括編輯前的代碼)??! 這里的鏈接可以隨意格式化和使用!
每次加載頁面時,都會執行級別 function,如果您根本不希望這種情況發生或經常發生,那么您可以 go 與 http 請求 -
或者您可以使用自定義緩存,例如將菜單內容存儲在 session 中,或者在頁面之間傳輸(無論如何您支付的通信費用,加載更多文本沒有區別)菜單內容,那么如果當前鏈接是在同一級別上,然后使用緩存菜單,如果不是,則運行新查詢。 這樣可以減少數據庫通信。
<?php
// Make a MySQL Connection
mysql_connect("localhost", "root", "") or die(mysql_error());
//select database
mysql_query("drop database if exists `my_test`;")or die(mysql_error());
mysql_query("create database `my_test`;")or die(mysql_error());
mysql_select_db("my_test") or die(mysql_error());
//create table
mysql_query(" drop table if exists `menu_item`;")or die(mysql_error());
mysql_query("
CREATE TABLE `menu_item` (
`item_id` MEDIUMINT(8) UNSIGNED NOT NULL ,
`item_title` VARCHAR(100) NOT NULL ,
`item_url` VARCHAR(200) NULL ,
`item_level` TINYINT UNSIGNED NOT NULL ,
`order` TINYINT UNSIGNED NOT NULL ,
PRIMARY KEY (`item_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (0, 'titile_000', 'http://www', 0, 0 ) ") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (1, 'titile_111', 'http://www', 0, 1 ) ") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (2, 'titile_222', 'http://www', 0, 2 ) ") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (3, 'titile_333', 'http://www', 0, 3 ) ") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (4, 'titile_444', 'http://www', 1, 0 ) ") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (5, 'titile_555', 'http://www', 1, 1 ) ") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (6, 'titile_666', 'http://www', 1, 2 ) ") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (7, 'titile_777', 'http://www', 1, 3 ) ") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (8, 'titile_888', 'http://www', 2, 0 ) ") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (9, 'titile_999', 'http://www', 2, 1 ) ") or die(mysql_error());
mysql_query("INSERT INTO `menu_item`
VALUES (10, 'titile_010', 'http://www', 2, 2 ) ") or die(mysql_error());
function get_level($level )
{
//get level
$result = mysql_query("SELECT `item_title`, `item_url`, `item_level`, `order` FROM `menu_item`
where `order` = '0' or `item_level` ='{$level}' order by `item_level` , `order` ;")
or die(mysql_error());
$output='<b>_____MENU_____</b><br>';
while($row = mysql_fetch_row($result))
{
$prefix=($row[3]==0)?$row[2].'. ':' '.$row[2].'.'.$row[3].' ';
$output.= $prefix.$row[0].' | '.$row[1].'<br>';
}
echo $output;
}
get_level(0);
?>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.