【问题标题】:kohana 3: How to create a route for a backend part?kohana 3:如何为后端部分创建路由?
【发布时间】:2011-11-14 16:26:59
【问题描述】:

我在 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

但它不...知道为什么吗?

【问题讨论】:

    标签: php routes kohana kohana-3


    【解决方案1】:

    问题是您的路线中有&lt;directory&gt;。这将在 Kohana 尝试加载您的路线时更改目录值。您的后端路由应如下所示。

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

    注意:这条路线必须在您的默认包罗万象路线之前。否则 Kohana 将永远无法到达您的路线。

    【讨论】:

    • 不,我也试过这个,但没有解决任何问题。 route::set 中的 将被默认数组中的 'directory' 值替换...
    • @Piero 我猜你已经偏离了 Kohana 的类命名结构,这会导致 Kohana 的路由失败。你能举一个路线的例子吗?它应该映射到的类以及类的位置。
    【解决方案2】:

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

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

    由于您按该顺序添加它们,因此名为“默认”的路由将仅匹配三个以上的段,例如此 uri:user/purcheses/view/42。当路由“默认”无法匹配 uri 时,将检查下一个路由。在您的情况下,名为“后端”的路由。

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

    您可以将 &lt;directory&gt; 替换为硬编码值,为 the 添加正则表达式或创建 lambda/回调路由。

    按顺序:

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

    【讨论】:

    • 我理解你的方法,但你的功能在最后一个 if 条件下有点不清楚。我了解对控制器文件夹等的搜索,但我为什么要这样做? Kohana 应该有一个强大的路由系统,易于配置,这对我来说似乎是一个 hack。
    • 如果 $directory 为空,则第一段不反映文件夹。由于反向路由路由包含一个非可选的 ,我们可以说它与该路由不匹配。如果它确实反映了文件夹,请将剩余的 uri(注意 array_shift())与“默认”路由匹配。如果匹配,则将目录添加到参数并返回。您应该为该路由提供与“默认”路由相同的默认值。请记住,这只是您如何实现它的一个示例。该路由还应该将 user/repository/admin/dashboard 路由到 classes/controller/user/repository/admin/dashboard.php
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

      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 路由放在首位,它将被选择用于任何 url 模式,例如: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'
      );
      

      【讨论】:

      • 实际上我已经尝试过了,但没有成功...我将它上下移动并重命名并更改了 conf,但什么也没做...我认为这是与 .htaccess 相关的问题。 ..但仍然无法解决...无论如何感谢您的帮助! :)
      • 当没有路由匹配时,将抛出 Http_Eception_404。名为“默认”的路由没有什么特别之处。它是作为示例并在删除 install.php 后给出“hello world”响应。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-21
      • 2013-12-26
      • 2011-03-25
      相关资源
      最近更新 更多