如何在Kohana中使用控制器深度超过2个目录

时间:2012-09-02 09:04:58

标签: php url-routing kohana-3.2

我有一个统计数据,其中有许多可以用于改进,这是我的页面中的一个模型。我最初将页面构建为一个巨大的控制器,具有像“action_editimprovementstat”这样的愚蠢行为。

所以我试图把东西搬到目录中,所以我把所有东西都放在了“[/] / controller / about”中,我把东西搬进了透视文件夹,例如:“[...] / controller /约/改进/ STAT“

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

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

以下是我更喜欢的控制器网址示例: /关于 /约/内部 /约/外部 /约/改进 /约/改进/ STAT

那些也会有行动,例如: /约/改进/编辑/ 6 /约/改进/ STAT /删除/ 7

如果存在歧义问题,我愿意妥协。 (顺便说一下,如果我通过单个控制器进行自己的路由,我想我可以管理一种方式,但我想知道是否有更好的方法,或者这种方式是否有详细记录[因此我可以从其他人的经验中学习]。 )

2 个答案:

答案 0 :(得分:1)

如果你活着,你可以简单地在路线上添加额外的变量或常数值。

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

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部分决定做什么。

答案 1 :(得分:1)

自从我学习了Kohana之后,我的编程经验得到了极大的改善,因为在Kohana之前我从未想过如何构建我的网址。在使用Pretty URL的MVC世界中,您可以真正思考您想要做什么以及如何去做。

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

在我看来,“约”实际上是一种行动,而不是一种控制者。网址“/ 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属于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'
    ))

就个人而言,我会避免设置这样的路线并真正重新考虑如何设置您的网址,以便创建合理的设计策略。