Kohana 3.2路由重写动作

时间:2011-12-28 10:17:02

标签: routing kohana rewrite

我有一个类似<country>/<id>_<action>/<name>的uri方案,它来自旧网站,我将网站移植到Kohana framewerk。可能的网址为http://www.example.com/us/1234_1/foo

<action>的值是0到9之间的数字:\d。每个数字指的是一个动作,例如0overview

如何在引导程序中设置路由,并将请求的操作正确移植。

这就是我现在所拥有的,但显然它的行为不正确,因为它试图调用函数Action_0而不是Action_Overview,给出了示例url:

Route::set('default'), '<country>/<id>_<action>/<name>')
     ->defaults(array(
        'controller' => 'index',
        'action'     => 'index'
     ));

2 个答案:

答案 0 :(得分:2)

一种解决方案是将动作action_0命名为action_9,但我们中的任何一个都喜欢这样。

另一个解决方案是在Controller :: before()中“重新路由”这个动作,如下所示:

public function before()
{
    parent::before();

    $actions = array(0 => 'overview', ...);

    $this->request->action($actions[$this->request->action()]);
}

或者你可以在lambda / callback路由中执行此操作,但我会将它保存在Controller :: before()中。

答案 1 :(得分:0)

使用干净的解决方案当然会很好,但我担心没有可用的解决方案。我可以想到几种方法来处理它,但是没有一种方法是理想的。

否1。 Darsstar提供的子路由提示

否2. 与解决方案相似。 1,但使用双路系统,顺序如下:

Route::set('default'), '<country>/<id>/<action>/<name>', array ('country' => '.+', 'name' => '.+', )) /* new */
 ->defaults(array(
    'controller' => 'new',
    'action'     => 'index'
 ));

Route::set('legacy'), '<country>/<id>_<oldaction>/<name>', array ('country' => '.+', 'name' => '.+', 'oldaction' => '\d+', )) /* legacy */
 ->defaults(array(
    'controller' => 'legacy',
    'action'     => 'route'
 ));

新控制器会根据您的喜好使用action_overview()等,而旧版只能执行一项操作,action_route()执行以下操作:

public function action_route ()
{
  $actions = array (0 => 'overview', ...);

  $params = array (
    'country' => $this->request->param ('country'),
    'id' => $this->request->param ('id'),
    'action' => $actions[$this->request->param ('oldaction')],
    'name' => $this->request->param ('name'),
  );
  $this->request->redirect (Route::get ('legacy')->uri ($params));
}

No 3。只是简单地使用多条路线,如果动作次数不是很多,请考虑按行动使用一条路线:

Route::set('overview'), '<country>/<id>_0/<name>')
 ->defaults(array(
    'controller' => 'index',
    'action'     => 'overview'
 ));

Route::set('details'), '<country>/<id>_1/<name>')
 ->defaults(array(
    'controller' => 'index',
    'action'     => 'details'
 ));

通过使用foreach(),您可以使其更容易管理:

$actions = array (
  'overview',
  'details',
);
foreach ($actions as $idx => $action)
{
  Route::set($action), '<country>/<id>_' . $idx . '/<name>')
    ->defaults(array(
      'controller' => 'index',
      'action'     => $action,
   ));
}

完成此操作后,您可以使用具有操作action_overview()的控制器。在生产中,使用路由缓存以避免在每个请求上重新定义它们。

就个人而言,如果它是一个直接的端口,并且没有计划扩展具有新功能的网站,我个人会选择3。否则我会选择2,因为它允许传统模式随着时间的推移逐步淘汰。此外,它允许更灵活的“新”路线 我不会选择1只因为它 - 在我看来 - 不符合Kohana编码风格,我个人希望在 bootstrap.php 中找到路由规则init.php (在模块的情况下)。这是一个非常有效的解决方案(在某种意义上它是Kohana的风格,因为Kohana足够灵活,允许解决方案违背它的一般风格...... :))