首先,对于这个问题的长度,我深表歉意。我想让它尽可能详细。
我正在用CakePHP开发一个基于Web的应用程序。在过去的几周里,我一直在研究几个方面,目前正在用大量信息填充我的数据库表。用户应该很容易通过美观、用户友好的 URL 访问它。假设我有我的Users
和 ACO、ARO 等都设置好了。这一切都与这个问题分开。我的数据库针对这个特定问题的相关方面如下:
:总体类别(例如,"猫")
- 每个类别
hasMany
主题
:特定主题(例如"喂食")
- 每个主题
belongsTo
一个类别 - 每个主题
hasMany
部分
:主题中的分区(例如,"肉类")
- 每个部分
belongsTo
一个主题 - 每个部分
hasMany
子部分
:分区中的小节(例如"已煮熟")
- 每个小节
belongsTo
一节
等等等等。
我在/Config/routes.php
文件中配置了路由,以包括以下内容:
Router::connect('/KnowledgeBase', array('controller' => 'categories', 'action' => 'index'));
Router::connect('/KnowledgeBase/:category', array('controller' => 'categories', 'action' => 'view'));
Router::connect('/KnowledgeBase/:category/:topic', array('controller' => 'topics', 'action' => 'view'));
Router::connect('/KnowledgeBase/:category/:topic/:section', array('controller' => 'sections', 'action' => 'view'));
Router::connect('/KnowledgeBase/:category/:topic/:section/:subsection', array('controller' => 'subsections', 'action' => 'view'));
如您所见,每种 URL 格式都链接到特定的控制器,以便用户可以键入 URL 例如 http://www.mysite.com/KnowledgeBase/Cats/Feeding/Meat/Cooked 或 http://www.mysite.com/KnowledgeBase/Cats/Grooming,它会将它们放在正确的页面上,由正确的控制器处理(在这两个示例中分别subsections
和topics
)。
这就是我有点卡住的地方。此数据需要验证。我很有可能在未来设置主题/部分/小节具有相同名称的内容。使用简单的$params
搜索小节理论上可能会导致问题,如果数据没有递归验证。
以我的狗类别为例:http://www.mysite.com/KnowledgeBase/Cats/Feeding/Meat/Cooked而不是:http://www.mysite.com/KnowledgeBase/Dogs/Feeding/Meat/Cooked
当我降落在特定的控制器(在本例中是我的SubsectionsController
)时,我只需要选择标题为 Cooked
的小节,该小节属于主题下Meat
部分Feeding
标题为 Dogs
(而不是 Cats
、Leopards
、Armadillos
或 Dolphins
...我离题了)。
最好的方法是什么?到目前为止,我可以看到两个潜在的选择:
- 将所有这些URL路由到一个特定的控制器(例如,无所不知的
KnowledgeBaseController
),并根据请求的数据使用recursive => 3
调用处理所有内容。 - 单独处理此信息,以便将我的
SubsectionsController
设置为recursive => -3
并确保数据具有有效的父项。 - 混合使用这些选项 - 使用中央
KnowledgeBaseController
使用recursive => X
查找查询验证数据,然后将所有这些信息发送到有问题的单个控制器进行查看。
我知道我的代码应该尽可能干燥,这意味着我应该只使用一个中央控制器来验证 URL $params
。但是,类别,主题,部分,子部分具有非常不同的布局,我宁愿它们由自己的控制器处理,同时保持这种URL格式。最好的方法是什么?是否有"最佳实践"解决方案?
谢谢。
首先,您列出的路由应按相反的顺序排列。最具体的路线在顶部,最通用的路线在底部。
您应该使用选项 #2。每个层次结构级别都由其自己的控制器管理。所以拿eg。在层次结构子节的最底层,您将有一个子节控制器,并在它的子节模型上找到具有适当递归值的子节模型,以获取其相关部分、该部分的主题等(顺便说一句,递归 = 3 仍然,没有递归 = -3 这样的东西)。因此,通过这种方式,您拥有层次结构的所有记录,并且可以使用层次结构的相关记录验证每个 url 片段。 $this->request->params
将包含路由的每个路由元素的键。