kohana 3:如何为后端部分创建路由?

时间:2011-11-14 16:26:59

标签: php routes kohana kohana-3

我在kohana 3.2应用程序的/ application / classes / controller /中创建了一个“后端”文件夹。

所以我有一个文件夹结构,如:

/application
+/classes
++/controller/
+++/A_controller.php
+++/Another_controller.php
+++/backend/
++++/A_Backend_controller.php

我的bootstrap.php中的路由:

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

Route::set('backend', '<directory>(/<controller>(/<action>(/<id>)))')
->defaults(array(
        'directory' => 'backend',
        'controller' => 'home',
        'action'     => 'index',
    ));

我有一个.htaccess重写我的URL并从url中删除“index.php”,所以我通常会调用这样的页面: www.mysite.com/controller_name/action_name

从我在路线文档中读到的内容,以及我写的“后端”路线,这应该有效: www.mysite.com/backend/controller_name/action_name

但它没有......任何想法为什么?

4 个答案:

答案 0 :(得分:2)

问题是您的路线中有<directory>。当Kohana尝试加载您的路线时,这将更改目录值。你的后端路线应该是这样的。

Route::set('backend', 'backend(/<controller>(/<action>(/<id>)))')
    ->defaults(array(
        'directory' => 'backend',
        'controller' => 'home',
        'action'     => 'index',
    ));

注意:此路线必须在您的默认全能路线之前。否则Kohana永远不会走你的路。

答案 1 :(得分:1)

您定义了两个路由,并且不会为任何段“重载”正则表达式。段的默认正则表达式为[^/.,;?\n]++,因此每个段都必须与该正则表达式匹配。

您的第一条路线是Kohana开箱即用的路线。它将匹配由斜杠分隔的0,1,2和3段。 您的第二条路线将匹配1,2,3和4段。

由于你按照这个顺序添加它们,名为“default”的路由只能匹配多个三个部分,例如uri:user / purcheses / view / 42。当路线'default'与uri不匹配时,将检查下一条路线。在您的情况下,路线名为'backend'。

如果你交换两条路线的顺序,那么路线“后端”将是第一条,并且只会失败0条或更多条4条。使用0段时,路由'default'将匹配它,并且5个或更多段将抛出Http_Exception_404。 但是当你首先放置'后端'时,它只会路由到子目录中的控制器,这很可能会破坏很多页面。

您可以用硬编码的值替换<directory>,为其添加正则表达式或创建lambda / callback路由。

按顺序:

Route::set('backend', 'backend(/<controller>(/<action>(/<id>)))')
->defaults(array(
        'directory' => 'backend',
        'controller' => 'home',
        'action'     => 'index',
    ));

Route::set('backend', '<directory>(/<controller>(/<action>(/<id>)))', array('foo|bar|backend'))
->defaults(array(
        'directory' => 'backend',
        'controller' => 'home',
        'action'     => 'index',
    ));

// not tested
Route::set('nested', function($uri, $directory = '')
{
    if ( ! $segments = explode('/', $uri))
        return;

    // get a multidimensional array of the Cascading File System with classes/controller as the root
    $list = Kohana::list_files('classes/controller');

    foreach($segments AS $segment)
    {
        if ( ! isset($list['classes/controller/'.$directory.$segment]))
            break;

        // we found a new existing directory, append it
        $directory .= array_shift($segments).DIRECTORY_SEPARATOR;

        // reduce $list to the remaining possible paths
        $list = $list[rtrim('classes/controller/'.$directory, DIRECTORY_SEPARATOR)];
    }

    if ( ! empty($directory) AND $params = Route::get('default')->matches(implode('/', $segments)))
    {
        $params['directory'] = rtrim($directory, DIRECTORY_SEPARATOR);

        return $params;
    }
},
    // this is used for reverse routing
    '<directory>(/<controller>(/<action>(/<id>)))')
->defaults(array(
        'controller' => 'dashboard',
        'action'     => 'index',
    ));

答案 2 :(得分:1)

正如韦德所说,你的路线后端必须在你的默认路线之前。

然后检查后端文件夹中是否有home.php,控制器定义如下:

class Controller_Backend_Home extends Controller {
    public function action_index(){
    }
} 

答案 3 :(得分:0)

这是我在我的一个应用程序中使用的

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

Route::set('user', '(<controller>(/<action>(/<id>)))')
    ->defaults(array(
            'controller' => 'user',
            'action'     => 'index',
    ));

它将如何运作?

  • 根据Kohana,首先列出的路线获得最高优先级。
  • 如果找不到任何路线的匹配,则会回退到default路线

首先,如果我们想使用目录结构,我们需要首先列出那些基于目录的路由。如果您看一下,如果我们应该首先列出user路由,则会选择任何网址模式,例如:http://example.com/directory/controller/action

为了避免这种情况,我们需要在directory based路由之后列出这种路由。是的,这很奇怪。但这就是它对kohana的作用。我希望Kohana能改善这种行为。

更新尝试使用Lambda/Callback route logic进行调试。它可能解释了一切。

Route::set('testing', function($uri)
{
    if ($uri == 'foo/bar') // check the prefix for "backend"
        return array(
            'controller' => 'welcome',
            'action'     => 'foobar',
        );
    },
    'foo/bar'
);