【问题标题】:ZF2: Child route is never matched – why?ZF2:子路由永远不会匹配——为什么?
【发布时间】:2015-04-18 22:58:16
【问题描述】:

Zend Framework 2 中我的模块的module.config.php 如下所示:

return array(
    'controllers' => array(
        'invokables' => array(
            'Test\Controller\A' => 'Test\Controller\AController',
            'Test\Controller\B' => 'Test\Controller\BController',
            'Test\Controller\C' => 'Test\Controller\CController',
        ),
    ),

    'router' => array(
        'routes' => array(
            'some-test' => array(
                'type' => 'literal',
                'options' => array(
                    'route' => '/a',
                    'defaults' => array(
                        'controller' =>  'Test\Controller\A',
                        'action' => 'index',
                    ),
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    'some-other-test' => array(
                        'type' => 'segment',
                        'options' => array(
                            'route' => '[/:controller[/:action]]',
                            'defaults' => array(
                                'action' => 'index',
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),

    'view_manager' => array(
        'template_path_stack' => array(
            __DIR__ . '/../view',
        ),
    ),
);

文字路由有效,/a 正确匹配,而/a/ 导致 404,这很好且合乎逻辑。

使用分段路线,情况看起来有点不同。无论我输入什么,路线都从不匹配。所以路由/a/b 失败了,我不明白。

根据上面的子路由设置,尾部斜杠是可选的,但是当它在那里时,还需要指定控制器名称。如果是这种情况,则应调用指定控制器的索引操作 - 在此示例中来自 BController。
如果在控制器名称后添加斜杠,则需要指定操作。

即使我输入/a/b/index,我也会收到 404 错误:

The requested controller could not be mapped to an existing controller class.

Controller:
b(resolves to invalid controller class or alias: b)

由此我得出结论,整个子路由它不起作用,而不仅仅是默认/后备选项。为什么子路由永远不匹配?

【问题讨论】:

  • 我怀疑可选部分可能会导致匹配失败'route' => '[/:controller[/:action]]', -> 'route' => '/:controller[/:action]',
  • 您确定在/a/b 上没有收到无效控制器错误吗?
  • @Xerkus 我刚试过你的路线,它也不起作用。我不确定什么是无效的控制器错误,但我得到的错误实际上只是我的问题中的一个。
  • /a/b/index 的错误表明您的路线有效。因此,如果您没有收到与 /a/b 相同的错误,那么会发生一些奇怪的事情
  • 您可以在invokables 中更改控制器的别名,如下所示:'a' => 'Test\Controller\AController', 'b' => 'Test\Controller\BController', 'c' => 'Test\Controller\CController',。我认为它会工作

标签: php zend-framework2


【解决方案1】:

您收到的错误是 Zend 路由器无法将控制器 b 映射到现有类。它需要知道您的控制器类在应用程序中的位置。

一种可能的解决方案是在module.config 文件中的invokables 中将控制器的名称作为别名。例如:'a' => 'Test\Controller\AController' 代表 AController。路由 /a 匹配并且不会抛出错误,因为您在路由配置中设置了默认控制器。

因此,您只需更改这部分代码。这样,控制器将在 invokables 数组中使用其 key value 调用:

'controllers' => array(
        'invokables' => array(
            'a' => 'Test\Controller\AController',
            'b' => 'Test\Controller\BController',
            'c' => 'Test\Controller\CController',
        ),
 ),

另一种解决方案是在路由配置中添加控制器的__NAMESPACE__,这样您就可以保留与现在相同的别名。

只需像这样修改您的代码:

'router' => array(
    'routes' => array(
        'some-test' => array(
            'type' => 'literal',
            'options' => array(
                'route' => '/a',
                'defaults' => array(
                    '__NAMESPACE__' => 'Test\Controller',//<---add it here
                    'controller' =>  'Test\Controller\A',
                    'action' => 'index',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                'default' => array(
                    'type' => 'segment',
                    'options' => array(
                        'route' => '[/:controller[/:action]]',
                        'defaults' => array(
                            'action' => 'index',
                        ),
                    ),
                ),
            ),
        ),
    ),
),

【讨论】:

  • 谢谢,非常好的答案。很高兴知道有两种方法可以解决这个问题!
  • 不客气。子路由中不需要'__NAMESPACE__' =&gt; 'Test\Controller',只是测试了一下。我已经编辑了我的答案;)
  • __NAMESPACE__ 不推荐使用,默认不注册。除非您在自己的应用程序中使用它,否则最好避免使用它。推荐的方法是为每个控制器创建显式路由。在 ZendSkeletonApplication 监听器注册在 Application 模块 Module::onBootstrap().
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多