如何显示类别和子类别?
如何显示类别和子类别? 我在DB中有一个表。排在这张表看起来是这样的:如何显示类别和子类别?
CREATE TABLE IF NOT EXISTS `category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`parent_id` int(11) NOT NULL,
`order` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM
我想显示类别和子类别喜欢上这个网站:http://www.dealsdirect.com.au/c/baby-1/(左侧菜单)
我尝试:
<?php
include 'Category_model.php';
include 'Advert_model.php';
$nr = $_GET['id'];
function show_category($nr){
try
{
$pdo = new PDO('mysql:host=localhost;dbname=advert', 'root', '');
$pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo -> query("SELECT * FROM category where `parent_id` = $nr");
echo "<ul>";
foreach ($stmt as $row){
echo "<li><a href=category_view.php?id={$row['id']}> {$row['name']}</a>".show_category($row['id'])."</li>";
}
echo "</ul>";
//$id = $_GET['id'];
}
catch(PDOException $e)
{
echo 'Error!: ' . $e->getMessage();
}
}
show_category($nr);
随着像这样的结构,您需要先为所选项目构造一个查询,然后再为所选项目父项构造一个查询。从本质上讲,您需要查询每个级别的菜单,这应该是可见的。
这就是树状关系的parent_id方案效率不高的原因。更好地使用嵌套集(http://en.wikipedia.org/wiki/Nested_set_model)或物化路径(http://en.wikipedia.org/wiki/Materialized_path)。如果您希望对这些项目进行一些更新,从长远来看,物化路径可能会更容易处理 - 我个人更喜欢它,尝试了两者。
根本没有。您可以选择所有行,理想情况下可以通过id对它们进行索引,然后遍历并生成结果。 – 2012-01-04 21:56:40
这是浪费资源,因为你不需要所有的结果 - 可以隐藏大量的子类别项目,你不需要任何细节。除此之外,如果你有一个合适的结构,在php中遍历和创建结果将比在数据库中做得慢。 – Fake51 2012-01-05 09:09:48
下面的代码应该让你开始。这是一个“递归函数” - 一个自我调用的函数。正如@ Fake51刚刚提到的那样,它效率不高,但它应该可以工作。
您需要一些CSS来构建您制作的列表。
function showItems($parent = 0) {
$q = "SELECT id, name FROM category WHERE parent_id = $parent";
$q = mysql_query($q);
if(mysql_num_rows($q)) {
echo "<ul>";
while($r = mysql_fetch_row($q)) {
echo "<li>";
echo "<a href=\"page.php?id=".$r[0]."\">".htmlentities($r[1])."</a>";
showItems($r[0]);
echo "</li>"\n;
}
echo "</ul>\n";
}
}
showItems();
编辑:既然还是有一直没有公认的答案,这是我的修饰一个SQL查询应该是更有效的,虽然有点更加混乱可能做这一切的代码。看看它是如何为你。
//Recursive function to show menu items from a passed in array
function showItems(&$menu, $parent = 0) {
if(is_array($menu[$parent]) && sizeof($menu[$parent])) {
echo "<ul>";
foreach($menu[$parent] as $num=>$name) {
echo "<li>";
echo "<a href=\"page.php?id=".$num."\">".htmlentities($name)."</a>";
showItems($menu, $num);
echo "</li>\n";
}
echo "</ul>\n";
}
}
//Create a multi-dimensional array of ALL menu items, separated by parent
$menu = array();
$q = "SELECT id, name, parent_id FROM category ORDER BY order";
$q = mysql_query($q);
while($r = mysql_fetch_row($q)) {
$menu[$r[2]][$r[0]] = $r[1];
}
//Call the function
showItems($menu);
你首先需要连接mysql_connect()并用mysql_select_db()选择一个数据库。如果需要,您应该可以将其转换为与PDO一起使用。 – SpoonNZ 2012-01-04 21:38:09
谢谢。这很有帮助 – user1050014 2012-01-04 21:40:38
这太可怕了。我宁愿做一个选择,获得所有类别的数组,然后使用该数组。另外,如果您可以向类别表'has_children'添加另一个字段并存储值,如yes/no或boolean,这将允许您使用更高效的算法 – 2012-01-04 21:54:24
既然你只需要类别及其所有子类别显示你不需要的菜单结构递归,你当然不希望在你的DB调用递归。所以最基本的解决方案(所有代码在一个文件中)将是这样的:
<?php
include 'Category_model.php';
include 'Advert_model.php';
$pdo = new PDO('mysql:host=localhost;dbname=advert', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$nr = $_GET['id'];
$sql = 'SELECT * FROM category where `parent_id` = :id or `id` = :id';
$stmt = $pdo->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->execute(array(':id' => $nr));
$menuCategories = $sth->fetchAll();
// If sub category id is passed fetch whole menu
if ((1 == count($menuCategories)) && ($nr == $menuCategories[0]['id'])) {
$nr = $menuCategories[0]['parent_id'];
$stmt->execute(array(':id' => $nr));
$menuCategories = $sth->fetchAll();
}
$parentCategoryFormat = '<h5><a href="category_view.php?id=%s">%s</a></h5>';
$subCategoryFormat = '<li><a href="category_view.php?id=%s">%s</a></li>';
$parentCategoryHTML = '';
$subMenuHTML = '';
foreach ($menuCategories as $row) {
if ($row['id'] == $nr) {
$parentCategoryHTML = sprintf($parentCategoryFormat, $row['id'], htmlentities($row['name'])); // Render parent category
} else {
$subMenuHTML .= sprintf($subCategoryFormat, $row['id'], htmlentities($row['name'])); // Render subcategory
}
}
echo $parentCategoryHTML;
if (!empty($subMenuHTML)) {
echo "<ul>{$subMenuHTML}</ul>";
}
那么,最新的问题是什么? – KingCrunch 2012-01-04 21:29:19
我不知道该怎么做。请“算法”/步骤怎么办 – user1050014 2012-01-04 21:32:34