Kohana 3.2 路由重写动作

发布于 2024-12-22 22:32:38 字数 654 浏览 0 评论 0原文

我有一个类似于 /_/ 的 uri 方案,它源自旧站点,我正在将该站点移植到 Kohana 框架。可能的 URL 为 http://www.example.com/us/1234_1/foo

的值为 0 到 9 之间的数字:\d。每个数字都代表一个操作,例如0概述

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

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

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

I have a uri scheme which is like <country>/<id>_<action>/<name> which descends from an old site and I am porting the site to the Kohana framewerk. A possible URL is http://www.example.com/us/1234_1/foo

The value of <action> is a digit from 0 to 9: \d. Every digit refers to a action, e.g. 0 is overview.

How can I set my routing in the bootstrap, with the requested action ported correctly.

This is what I have now, but obviously it does not behave correctly, because it tries to call the function Action_0 instead of Action_Overview, given the example url:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

此生挚爱伱 2024-12-29 22:32:38

一种解决方案是将操作命名为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() 中。

One solution would be to name the actions action_0 to action_9, but I either of us likes that.

Another solution would be to 'reroute' the action in Controller::before() like this:

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

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

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

Or you could do that in a lambda/callback route, but I would keep it in Controller::before().

永不分离 2024-12-29 22:32:38

如果有一个干净的解决方案当然很好,但恐怕没有可用的解决方案。我可以想到一些方法来处理它,但是没有一个是理想的。

否 1。 将是 Darsstar 提供的子路由器想法

否 2。 与解决方案 1 类似。 1,但使用双路由系统,如下所示:

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

新控制器将根据您的喜好使用 action_overview() 等,而

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

旧控制器将仅保留一个操作 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));
}

否 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,因为它允许遗留模式随着时间的推移而逐步淘汰。此外,它还允许更灵活的“新”路线。
我不会选择 no 1,因为在我看来,它不符合 Kohana 编码风格,我个人希望在 bootstrap.php中找到路由规则init.php(对于模块)。否则,这是一个完全有效的解决方案(从某种意义上说,它是 Kohana 的风格,因为 Kohana 足够灵活,可以允许违背其一般风格的解决方案......:))

It would of course be nice with a clean solution, but I'm afraid there isn't one available. I can think of a few ways to handle it, none of them, however, ideal.

No 1. Would be the subrouter idea provided by Darsstar

No 2. Would be similar to solution no. 1, but use a dual route system, along the lines of:

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

and

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

The new controller would use action_overview() etc. to your liking and the legacy would hold only one action, action_route() doing something like this:

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. Would be to simply use multiple routes, if the number of actions aren't that great, consider using one route per action like this:

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'
 ));

You could make this a bit more manageable by using a foreach() along the lines of this:

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

When this is done, you can use a controller with action action_overview(). In production, use caching for the routes to avoid redefining them on each request.

Personally I would opt for no 3 if it's a straight port and there's no plans for extending the site with new functionality. Otherwise I'd go with no 2, because it allows for a legacy mode that can be phased out over time. Also, it allows for more flexible "new" routes.
I would not choose no 1 only because it's -- in my mind -- not in keeping with the Kohana style of coding, I would personally expect to find routing rules either in bootstrap.php or init.php (in the case of modules). It's a perfectly valid solution otherwise (and in a sense it is in the style of Kohana, in that Kohana is flexible enough to allow for solutions that goes against it's general style... :) )

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文