0

我有一个统计数据,其中可以存在许多改进,这是我的关于页面中的一个模型。我最初将页面构建为一个具有诸如“action_editimprovementstat”之类的愚蠢操作的巨型控制器。

所以我试图将东西移动到目录中,而不是所有东西都在“[...]/controller/about”中,我将东西移动到那里的透视文件夹中,例如:“[...]/controller/about/improvement /统计”

我更改了路由的正则表达式,因此控制器将接受斜杠,这由调试器判断是有效的,因为现在控制器文本将显示为“about/improvement/stat”,不幸的是它仍然告诉我请求的 url 可以'找不到。

那么,我问,拥有分层控制器结构的最简单方法是什么?

这是我更喜欢的控制器 URL 示例: /about /about/internal /about/external /about/improvement /about/improvement/stat

这些也会有动作,例如:/about/improvement/edit/6 /about/improvement/stat/delete/7

如果存在模棱两可的问题,我愿意妥协。(顺便说一句,如果我通过单个控制器进行自己的路由,我想我可以管理一种方式,但我想知道是否有更好的方式,或者这种方式是否有据可查[所以我可以从别人的经验中学习]。 )

4

2 回答 2

1

自从我学习了 Kohana 后,我的编程体验有了很大的提高,因为在使用 Kohana 之前,我从来没有考虑过我的 url 是如何构建的。在 MVC 世界中,使用 Pretty URLs 会让你真正思考你想要做什么以及如何去做。

在我看来,通过查看您在上面的示例中想要做的事情,在我看来您是在倒退。您说您首选的 URL 是: /about /about/internal /about/external /about/improvement /about/improvement/stat

在我看来,“关于”实际上是一个动作,而不是一个控制器。url "/about/" 非常令人困惑,因为它没有告诉我我正在获取什么信息,但我们可以放一张幻灯片,因为它可能与一般网站有关。“/about/internal”非常清楚,但在很多方面你都在尝试编写你的网址,以便它们以正确的英语阅读。实际上,我会将它们写为:/about、/internal/about、/external/about、/improvement/about、/improvement_stat/about

我不确定您为什么拒绝拥有多个控制器,除非您将控制器设置为模板控制器,并且您认为您必须为每个控制器都这样做。你没有。一般来说,我创建一个名为“page”的控制器,它是我的模板控制器。然后所有其他控制器扩展页面控制器。我可以在页面控制器中定义可以在扩展页面控制器的所有控制器中使用的常量和其他变量。

但是如果你真的拒绝编写多个控制器,你总是可以编写特定的路由来让你到达你想要的任何控制器和动作。例如,我使用一个路由进行比较,我希望最多 4 个 id 传递到我的路由中。我这样写了这条路线:

Route::set('thing_compare', 'thing/compare/<thing1>/<thing2>(/<thing3>(/<thing4>))')
    ->defaults(array(
        'controller' => 'thing',
        'action'     => 'compare'
    ));

请注意,thing3 和 thing4 在括号中,这意味着它们是可选的。然后在我的控制器中,我可以通过执行以下操作来获取这些值:

$thing1 = $this->request->param('thing1');

但是回到您给出的示例,只需编写类似这样的路由(假设您的控制器名为“about”:

Route::set('about_internal', 'about/internal')
    ->defaults(array(
        'controller' => 'about',
        'action'     => 'about_internal'
    ));
Route::set('about_external', 'about/external')
    ->defaults(array(
        'controller' => 'about',
        'action'     => 'about_external'
    ))

就我个人而言,我会避免设置这样的路由,并真正重新考虑如何设置你的 url,以便它创建一个明智的设计策略。

于 2012-10-24T06:19:05.167 回答
1

如果您住的话,您可以简单地向路线添加其他变量或常量值。

Kohana 文档甚至显示了一个具体示例,其中在路由前面添加了一个额外的目录,该目录只能具有两个给定值之一:

Route::set('sections', '<directory>(/<controller>(/<action>(/<id>)))',
    array(
        'directory' => '(admin|affiliate)'
    ))
    ->defaults(array(
        'controller' => 'home',
        'action'     => 'index',
    ));

当然,您也可以在后面或中间添加值。唯一的要求是您的路线将始终至少产生一个控制器和一个动作。但它们实际上不必存在于 url 中。您可以指定与其他值匹配的路由,并为控制器和/或操作指定一个常量值,如下所示:

Route::set('search', ':<query>', array('query' => '.*'))
  ->defaults(array(
    'controller' => 'search',
    'action' => 'index',
  ));

最大的陷阱:重要的是要理解路由是按照添加的顺序匹配的,一旦一个 URL 匹配一个路由,路由本质上就“停止”了,其余的路由永远不会尝试。因为默认路由几乎匹配任何东西,包括一个空的 url,新路由必须放在它之前。也许这就是现在的问题?

无论如何,与其添加技巧来匹配斜线,我宁愿创建一个接受大量可选变量的路由,这样您就可以从通用控制器中读取 'urlpart1' 到 urlpartX'。也就是说,如果你需要。当然,设置是让您为不同的 url 创建不同的控制器,因此您不需要具有巨大方法的巨大控制器来根据 url 部分决定要做什么。

于 2012-09-02T09:23:11.367 回答