Kohana模块路由优先级

时间:2012-07-19 01:25:33

标签: routes kohana

我正在创建一个Kohana模块,并在该模块中动态创建路由。我希望路线优先于应用程序其余部分的路线。 (特别是默认的,全能路线)。

关于如何做到这一点的任何想法?

谢谢!

====== 更新:

我想我忘了提到我正在动态加载模块,如下所示:

Kohana::modules(array_merge(array($module_name=>$directory), Kohana::modules()));

然后我正在运行模块的HMVC请求,如下所示:

$response = Request::factory('versioned-api')
            ->method('POST')
            ->secure(true)
            ->post(array('data'=>serialize($request))) // Performing a straightforward POST
            ->execute();

2 个答案:

答案 0 :(得分:3)

关于Kohana(截至3.2)模块和路由优先级的一些背景知识:

  1. 按照Kohana::modules的顺序初始化模块。根据所需的路线优先级,这很重要。在您的示例Kohana::modules(array_merge(array($module_name=>$directory), Kohana::modules()));中,已放置在Kohana::modules()中的所有模块都已初始化。即使您将新模块合并到列表的开头,也会在调用Kohana::modules()时初始化模块。如果查看“system / classes / kohana / core.php”第565行,您会注意到“init.php”只需要一次(如果存在于模块中)。
  2. 路线按照添加顺序进行匹配。如果使用相同的路径名,它们也会被覆盖。
  3. 总之,Kohana本身没有办法将路线推到列表的开头。当然,保证首先加载有问题的模块可以解决您的问题(只要稍后不会覆盖该路径)。如果您可以透明地扩展Route,下面是如何通过将路由预先添加到堆栈的开头来加载模块来完成此操作:

    GitHub Gist(包括单元测试):https://gist.github.com/3148737

    <?php defined('SYSPATH') or die('No direct script access.');
    /**
     * Route transparently extended. Place in "classes" directory of Kohana 3+ application or module.
     */
    class Route extends Kohana_Route
    {
        /**
         * Prepend Route to beginning of stack. If name already exists further in the stack, it is 
         * removed.
         * 
         *  Route::prepend('default', '(<controller>(/<action>(/<id>)))')
         *      ->defaults(array(
         *          'controller' => 'welcome'
         *      ));
         * 
         * @static
         * @access  public
         * @param   string   route name
         * @param   string   URI pattern
         * @param   array    regex patterns for route keys
         * @return  Route
         */
        public static function prepend($name, $uri_callback = NULL, $regex = NULL)
        {
            // Ensure entry does not already exist so it can be added to the beginning of the stack
            if (isset(Route::$_routes[$name]))
            {
                unset(Route::$_routes[$name]);
            }
    
            // Create reference
            Route::$_routes = array_merge(array($name => NULL), Route::$_routes);
    
            // Overwrite reference
            return Route::$_routes[$name] = new Route($uri_callback, $regex);
        }
    }
    

答案 1 :(得分:2)

这是一个简单的路由示例:

// APPPATH/bootstrap.php
// define route before module loading
Route::set('route1', ...);
// load module list
Kohana::module(array(
    'module1'  => 'module1',
    'module2'  => 'module2',
));
Route::set('catch-all', ...);

module1和module2在mroute1中都有自己的路由(mroute2init.php)。因此,Kohana将使用此路由序列:

 1. `route1`    // defined in bootstrap before modules
 2. `mroute1`   // from first module
 3. `mroute2`   // from second module
 4. `catch-all` // this one was loaded after all modules
  1. 请注意,如果您在模块控制器或任何帮助器中的某处创建路径,则会在catch-all路由后添加。
  2. 您可以更改模块订单:Kohana::modules(array('module3' => 'module3') + Kohana::modules());会重新排序您的模块,module3将在列表中排在第一位。但是,这不会影响模块初始化的顺序。先前已初始化任何Kohana::modules来电。即使模块现在位于列表的开头,它也会在其他模块之后初始化(参见http://kohanaframework.org/3.2/guide/api/Kohana_Core#modules)。