2010-05-16 155 views
0

通常有一个类别菜单,每个菜单链接到一个类别页面,其中显示该类别下的所有项目。如何在每个类别下显示多个类别和产品?

现在我需要在同一页面中显示PHP/MySQL下的所有类别和项目。

所以它会是这样的。

Category 1 
description of category 1 
item 1 (some details, such as name, thumbnail etc for each item) 
item 2 
.. 

Category 2 
description of category 2 
item 5 
item 6 
.. 

Category 3 
description of category 3 
item 8 
item 9 
... 

... 

我在我的数据库中有类别和产品表。

看起来好像我必须通过类别循环,并在每个类别下循环以获取所有项目。

但我不知道如何继续。

CREATE TABLE IF NOT EXISTS `omc_product` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    `shortdesc` varchar(255) NOT NULL, 
    `longdesc` text NOT NULL, 
    `thumbnail` varchar(255) NOT NULL, 
    `image` varchar(255) NOT NULL, 
    `product_order` int(11) DEFAULT NULL, 
    `class` varchar(255) DEFAULT NULL, 
    `grouping` varchar(16) DEFAULT NULL, 
    `status` enum('active','inactive') NOT NULL, 
    `category_id` int(11) NOT NULL, 
    `featured` enum('none','front','webshop') NOT NULL, 
    `other_feature` enum('none','most sold','new product') NOT NULL, 
    `price` float(7,2) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; 



CREATE TABLE IF NOT EXISTS `omc_category` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    `shortdesc` varchar(255) NOT NULL, 
    `longdesc` text NOT NULL, 
    `status` enum('active','inactive') NOT NULL, 
    `parentid` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; 

我会感谢您的帮助。

在此先感谢。

回答

0

好像我通过 类别和在每个类别下我 必须遍历获得所有 项目必须循环。

  1. 你查询到让所有的类别
  2. 您循环您的类别•您显示的类别一般头•您查询获得该类别的
  3. 您遍历项目,并显示所有项目他们
0
SELECT A.`id` AS catid, A.`name` AS catname, ..., B.`id` AS prodid, ... 
FROM `omc_category` A LEFT JOIN `omc_product` B ON (B.`category_id` = A.`id`) 
ORDER BY A.`id` 

你dind't甚至需要按类别排序,但它使处理结果更容易。

注意:如果结果集非常大,我会倾向于Lo'oris的方法。

1

简单的方法:做一个查询来获取类别,然后单独查询来获取每个产品列表。喜欢的东西:

<?php 
    // Shortcuts to essential string-escaping functions 
    // 
    function h($s) { 
     echo htmlspecialchars($s, ENT_QUOTES); 
    } 
    function u($s) { 
     echo urlencode($s); 
    } 
    function m($s) { 
     return "'".mysql_real_escape_string($s)."'"; 
    } 

    // Get all categories 
    // 
    $q= mysql_query('SELECT id, name, shortdesc FROM omc_category WHERE status='active' ORDER BY id'); 
    $categories= array(); 
    while ($categories[]= mysql_fetch_assoc($q)) {} 
?> 

<?php foreach ($categories as $category) { ?> 
    <h2><?php h($category['name']); ?></h2> 
    <p><?php h($category['shortdesc']); ?></p> 
    <?php 
     // Get all products for a category 
     // 
     $q= mysql_query('SELECT id, name FROM omc_product WHERE status='active' AND category_id='.m($category['id'])); 
    ?> 
    <ul> 
     <?php while ($product= mysql_fetch_assoc($q)) { ?> 
      <li> 
       <a href="/product.php?id=<?php u($product['id']); ?>"> 
        <?php h($product['name']); ?> 
       </a> 
      </li> 
     <?php } ?> 
    </ul> 
<?php } ?> 

(注:m()呼叫这里并非绝对必要,因为整数是安全的插入到一个SQL查询,而不逃避,但它不是一个好主意,让成习惯,因为如果你这样做。它使用字符串,你会有一个SQL注入安全漏洞,我使用的是mysql_接口,在这里手动转义;在使用mysqli_或PDO的参数化查询中,通常情况下会好得多,这样可以防止你必须担心SQL转义,u()的URL编码也是如此:整数不是必须的,但通常值得养成使用习惯。)

对于一个简单的网站,这将是好的。对于具有多个类别的大型网站,你可能想要让所有的产品在一个单一的查询,你可以做这样的:

SELECT omc_product.id, omc_product.name, omc_product.category_id 
FROM omc_product 
JOIN omc_category ON omc_category.id=omc_product.category_id 
WHERE omc_product.status='active' AND omc_category.status='active' 
ORDER BY category_id, id 

,然后在你回来的每一行,检查,看看是否category_id已经改变自上一行以来。如果有,则输出前一个查询中对应的category对象的nameshortdesc。 (或者你可以在上面的查询选择omc_category.nameshortdesc也同时让他们,但你可能不希望这样做,如果该说明可能相当长。)

另外,考虑使用与InnoDB表在您的表格之间引用适当的FOREIGN KEY引用。今天使用MyISAM几乎没有什么理由(除了FULLTEXT)。

`parentid` int(11) NOT NULL, 

哦,我希望这并不意味着你已经有了分级类别!这会让一切变得更加复杂。另请参阅:嵌套集。

+0

如何“检查自上一行以来category_id是否已更改”?提前致谢。 – shin 2010-05-16 21:07:54

+0

在循环开始处设置'$ previouscatid = NULL',然后在循环中检查$ product ['category_id']!== $ previouscatid',并设置$ $ previouscatid = $ product ['category_id ']'就在循环结束之前。 – bobince 2010-05-16 21:12:26

相关问题