如何在Kohana有一个控制器,我有2个以上的目录深


How can I have more than 2 directories deep with a controller in Kohana

我有一个stat,其中可以存在许多用于改进的模型,这是我的about页面中的一个模型。我最初将页面构建为一个巨大的控制器,它有一些愚蠢的操作,比如"action_editimprovementstat"。

所以我试着把东西移到目录中,所以我没有把所有的东西都放在"[…]/controller/about"中,而是把东西移动到透视文件夹中,例如:"[…]/controller/about/improvement/stat"

我更改了路由的regex,因此控制器将接受斜杠,这由调试器判断是有效的,因为现在控制器文本将显示为"about/expression/stat",不幸的是,它仍然告诉我找不到请求的url。

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

以下是我更喜欢的控制器URL示例:/关于/关于/内部/关于/外部/关于/改进/关于/改进/stat

这些也会有行动,例如:/关于/改进/编辑/6/关于/改进/stat/delete/7

如果有模棱两可的问题,我愿意妥协。(顺便说一句,我认为如果我通过一个控制器进行自己的路由,我可以找到一种方法,但我想知道是否有更好的方法,或者这种方法是否有很好的记录[这样我就可以从别人的经验中学习]。

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"到"urlpart X"。当然,如果你需要的话,设置是为了让你为不同的url创建不同的控制器,所以你不需要一个庞大的控制器来根据url部分来决定该做什么。

自从我学习了Kohana之后,我的编程经验得到了极大的提高,因为在Kohana之前,我从未想过如何构建我的url。在MVC的世界里,使用Pretty URL会让你真正思考你想做什么以及如何去做

在我看来,从上面的例子中看你想做什么,在我看来你是在倒退。你说你更喜欢的URLS是:/about/about/internal/about/external/about/eimprovement/about/improvement/stat

在我看来,"大约"实际上是一个动作,而不是一个控制器。url"/about/"非常令人困惑,因为它没有告诉我我得到的信息是什么,但我们可以忽略它,因为它可能是关于网站的。"/about/internal"很清楚,但在很多方面,你都在努力编写网址,以便它们能用正确的英语阅读。事实上,我会把它们写为:/about,/internal/about,/external/about,/production/about和/production_stat/about

我不知道你为什么抗拒拥有几个控制器,除非你把你的控制器设置为模板控制器,也许你认为你必须为每个控制器都这样做。你没有。通常,我会创建一个名为"page"的控制器,这是我的模板控制器。然后所有其他控制器扩展页面控制器。我可以在页面控制器中定义常量和其他变量,这些变量可以在扩展页面控制器的所有控制器中使用。

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

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

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

$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,以便创建一个合理的设计策略。