上Kohana的一些背景(如3.2)模块和路由的优先级:
- 模块在顺序
Kohana::modules
初始化被调用。基于期望的路线优先权,这很重要。在你的例子中,Kohana::modules(array_merge(array($module_name=>$directory), Kohana::modules()));
,已经放置在Kohana::modules()
中的任何模块已经被初始化。即使您正在将新模块合并到列表的开头,模块也会被初始化为Kohana::modules()
。如果您查看“system/classes/kohana/core.php”第565行,您会注意到“init.php”只需要一次(如果存在于模块中)。
- 路由按照它们添加的顺序进行匹配。如果使用相同的路由名称,它们也会被覆盖。
总之,Kohana本身并没有将路线推到列表的开头。当然,保证首先加载相关模块将解决您的问题(只要稍后不会覆盖路由)。如果你能透明地扩展路线,下面是如果模块通过预先的路线到堆栈的开头加载以后你可以如何做到这一点:
GitHub的要点(包括单元测试):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);
}
}
哇!这比我想出的要优雅得多。我要回到这个并且以这种方式实现!最后,我创建了一个类似的地方,创建了一个Route类并覆盖了set函数,在这个函数中使用了static :: $ _ routes,array_reverse'd它们,做了一个parent :: set(),然后将它们反转回去。 但我更喜欢你的解决方案。谢谢! – 2012-07-20 08:05:12
太棒了!实施时,请务必查看上述Gist中的单元测试覆盖率。乐意效劳! – michealmorgan 2012-07-20 08:16:22