【问题标题】:How to work with multiple levels of subcategories in Codeigniter?如何在 Codeigniter 中处理多个级别的子类别?
【发布时间】:2014-02-27 18:44:38
【问题描述】:

在 Codeigniter 中处理多级子类别的最聪明的解决方案是什么?我想为旅行社制作一个提供旅行优惠的网站,其结构将如下所示:

- Cat1
- Cat2
--- Subcat1
--- Subcat2
------ Subcat1
--------- Subcat1
--------- Subcat2
------------ Subcat1
------------ Subcat2
--------------- offer1
--------------- offer2
--------------- offer3
--------------- offerN
------------ Subcat3
--------- SubcatN
------ Subcat2
------ SubcatN
--- Subcat3
--- SubcatN
- Cat3
--- offer1
--- offer2
--- offer3
--- offerN
- CatN

这是嵌套类别的示例。每个(子)类别都应包含:主图片、描述和子类别列表或商品列表。

我有一些想法用一个名为 Categories (ID, cat_name, parent) 的表来做这件事,如果父级为 0,则它是顶级类别,如果父级是某个 int,则该值是父类...

但我不知道如何使用控制器解决路由问题?我知道如何仅使用 2 个级别(主要类别和子类别)来做到这一点,但它们是手动添加到路线中的。我不知道如何动态执行此操作,因此将来可以通过管理面板添加更多类别和子类别。

当然,我会为我的报价准备另一张桌子,我知道这一点,我对此没有任何问题。问题是控制器结构会是什么样子?

对于我目前只有 1 级子类别且没有动态添加子类别选项的项目,这是我在 routes.php 中的内容

$route[‘cat1’] = “category”;
$route[‘cat1/(:any)’] = “category/subcategory”;

$route[‘cat2’] = “category”;
$route[‘cat2/(:any)’] = “category/subcategory”;

$route[‘cat3’] = “category”;
$route[‘cat3/(:any)’] = “category/subcategory”;

$route[‘cat4’] = “category”;
$route[‘cat4/(:any)’] = “category/subcategory”;

$route[‘cat5’] = “category”;

换句话说,cat1,2,3,4,5 是类别的真实名称,并且 :any 代表其所有子类别,当访问者键入 example.com/pc_news 时,它会被重定向到名为 category 的控制器它是索引函数。如果他键入 example.com/pc_news/hardware,那么他会被重定向到控制器类别的方法子类别。

如果我想添加更多类别和子类别,我会在路线上手动完成,但如果我想添加子子类别 (example.com/pc_news/hardware/something),我不知道如何实现。

在我想做的新项目上,我会有类似的东西:

example.com/summer/turkey/airplane/alanya/hotels # and it will list all the offers
example.com/summer/turkey/airplane/alanya/apartments
example.com/summer/turkey/bus/kushadasi
example.com/winter/bus/france/hotels
example.com/winter/airplane/france/hotels

有人知道怎么做吗?

【问题讨论】:

  • 您能给我们一些您想要的 URL 示例吗?我看到remapoing function calls 的一个可能的解决方案是查询获取正确的类别并触发正确的方法。
  • 我已经编辑了我的帖子,因为我的评论太大了,这里放不下,我举了一个例子。

标签: codeigniter nested categories


【解决方案1】:

至于路由,我只会使用路由配置将所有内容发送到一个方法,您可以在其中实现您想要的任何逻辑,如果您仍然想在该控制器内部访问方法,您必须在"catch any" 是这样的:

config/routes.php

$route['products/save/(.*)'] = 'products/save/$1';
$route['products/(.*)']      = 'products/index/$1';

设置完成后,您将获得 Products::index 方法中的每个参数:

控制器/products.php

class Products extends CI_Controller {
    public function index() {
        $args = func_get_args();
        // now $args holds the url segments 
        $categories = array();
        foreach ($args as $cat_name) {
           $categories[] = $this->db
               ->from('categories')
               ->where('cat_name', $cat_name)
               ->get()
               ->row();
        }
    }
}

至于存储类别,如果行中只有parent_id,则必须循环或使用一堆连接来获取每个类别。如果您只有 3-4 个级别,它可能不是真正的问题,也可能不会经常更改,因此可以轻松缓存。如果您想要更高效的解决方案,请查看nested set 模型。

更新(我已扩展链接论坛中的问题)

您可以使用特殊的404_override 键(位于页面底部)使每个请求都转到特定控制器的index 方法。 不要忘记您需要在Products 控制器中处理 404 url​​!

config/routes.php

$route['404_override'] = 'products';

原始答案可以扩展为执行此操作,将您不想发送到Products 控制器的所有内容(基本上每个其他控制器的名称)列入白名单,并在最后有一条包罗万象的路线将其他人发送到Products 控制器。 404 url​​还需要处理。

config/routes.php

// place any specific rules on top
$route['about'] = 'main/about';
// have whitelist existing controllers, make them go to their original place like it normaly would
$route['(controller1|controller2|controller3)(/?.*)'] = '$1$2';
$route['(:any)'] = 'products/index/$1'; // the last "catch all" row goes here

【讨论】:

  • 我已经编辑了我的帖子,因为我的评论太大了,这里放不下,我举了一个例子。
  • @MarkC:你确定你编辑了这个问题?我看不到待处理的修改,最后一次修改是在 4 小时前完成的。
  • 我不知道它是如何工作的。请告诉我在哪里发布编辑,它太大了,无法在评论中放置,我还能在哪里发布?
  • 答案标签中应该有一个[edit],如果你点击它应该会打开编辑表单。
  • 我已将您在 codeigniterforums 网址上的第二篇帖子复制到问题中,并更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 2016-01-05
  • 2017-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-24
相关资源
最近更新 更多